Typescript przypisujący interfejs lub typ do Record <string, string>
Po przeczytaniu tego pytania lub tego artykułu nadal jestem trochę zdezorientowany co do subtelnych różnic między interface
a a type
.
W tym przykładzie moim celem jest przypisanie prostego obiektu do szerszego Record<string, string>
typu:
interface MyInterface {
foobar: string;
}
type MyType = {
foobar: string;
}
const exampleInterface: MyInterface = { foobar: 'hello world' };
const exampleType: MyType = { foobar: 'hello world' };
let record: Record<string, string> = {};
record = exampleType; // Compiles
record = exampleInterface; // Index signature is missing
Spróbuj
Przypisanie jest możliwe przy deklarowaniu mojego obiektu za pomocą type
, ale nie przy deklarowaniu podobnego za pomocą interface
. Mówi, że brakuje podpisu indeksu, ale według mojego (ograniczonego) zrozumienia podpisów indeksu, żaden z nich nie ma MyType
i MyInterface
faktycznie go nie ma.
Jaki jest powód, dla którego ostatnia linia nie kompiluje się, a poprzednia tak?
Odpowiedzi
Record<string, string>
jest taki sam jak { [key: string]: string }
. Podzbiór może zostać przypisany do tego typu sygnatury indeksu jest możliwy tylko wtedy, gdy wszystkie właściwości tego typu są znane i można je sprawdzić pod kątem tego podpisu indeksu. W Twoim przypadku wszystko z exampleType
można przypisać do Record<string, string>
. Można to sprawdzić tylko dla typów literałów obiektowych, ponieważ typów literałów obiektowych nie można zmienić po ich zadeklarowaniu. W ten sposób znana jest sygnatura indeksu.
Źródło: https://github.com/microsoft/TypeScript/pull/7029
Natomiast interfejsy nie są ostateczne w momencie ich zadeklarowania. Zawsze istnieje możliwość dodania nowych członków do tego samego interfejsu ze względu na łączenie deklaracji.