Załóżmy, że istnieje plik do pisania dla biblioteki X, który zawiera kilka interfejsów.
interface I1 {
x: any;
}
interface I2 {
y: {
a: I1,
b: I1,
c: I1
}
z: any
}
Aby pracować z tą biblioteką, potrzebuję przekazać obiekt, który jest dokładnie tego samego typu co I2.y
. Mogę oczywiście stworzyć identyczny interfejs w moich plikach źródłowych:
interface MyInterface {
a: I1,
b: I1,
c: I1
}
let myVar: MyInterface;
ale potem spoczywa na mnie ciężar utrzymywania go na bieżąco z tym z biblioteki, ponadto może być bardzo duży i powodować duplikowanie kodu.
Czy zatem istnieje sposób na „wyodrębnienie” typu tej konkretnej właściwości interfejsu? Coś podobnego do let myVar: typeof I2.y
(co nie działa i powoduje błąd „Nie można znaleźć nazwy I2”). Z góry dziękuję.
Edycja : po zabawie trochę w TS Playground zauważyłem, że następujący kod osiąga dokładnie to, co chcę:
declare var x: I2;
let y: typeof x.y;
Jednak wymaga x
zadeklarowania zbędnej zmiennej . Szukam sposobu, aby to osiągnąć bez tej deklaracji.
źródło
Odpowiedzi:
Wcześniej nie było to możliwe, ale na szczęście jest teraz, ponieważ TypeScript w wersji 2.1 . Został wydany 7 grudnia 2016 roku i wprowadza indeksowane typy dostępu, zwane również typami wyszukiwania .
Składnia wygląda dokładnie jak dostęp do elementu, ale jest zapisana w miejsce typów. Więc w twoim przypadku:
interface I1 { x: any; } interface I2 { y: { a: I1, b: I1, c: I1 } z: any } let myVar: I2['y']; // indexed access type
Teraz
myVar
ma typI2.y
.Sprawdź to w TypeScript Playground .
źródło
I2['y'][0]
Zobacz: typescriptlang.org/play/...I2
typu. Jak uzyskać typ określonego klucza dynamicznie podczas wykonywania pętli. To;let z: typeof x[a];
, gdziea
jest określony klucz jako ciąg, nie działa. Mówi mi, żea
odnosi się do wartości i musi odnosić się do typu. Jak bym to zrobił? Czy jest to w ogóle możliwe? Dzięki!Interfejs jest jak definicja obiektu. Wtedy y jest własnością twojego obiektu I2, czyli jest pewnego typu, w tym przypadku "anonimowy".
Możesz użyć innego interfejsu do zdefiniowania y, a następnie użyć go jako swojego typu y w ten sposób
interface ytype { a: I1; b: I1; c: I1; } interface I2 { y: ytype; z: any; }
Możesz umieścić swój interfejs w pliku i użyć ekstraktu, aby móc zaimportować go do innych plików swoich projektów
export interface ytype { a: I1; b: I1; c: I1; } export interface I2 { y: ytype; z: any; }
Możesz to zaimportować w ten sposób:
import {I1, I2, ytype} from 'your_file'
źródło