There is a lookup type in TypeScript
Consider an interface provided externally with an embedded sub-type for one of its properties, like this:
// This one comes from an external library.
export interface SomeClass {
// The return value does not have an exported return type.
something: {foo: number, bar: string, baz: boolean}
}
If we want to stub SomeClass in our code and are interested in only a subset of the things in something
, we obviously can’t do something like:
// This causes a compile error.
const stub: SomeClass = {
something: {
foo: 1
}
}
We should cast the stubbed something
appropriately. One solution is to do the extraction (which should have happend in the library on our side):
// This is copy+pasted from the external library.
type SomethingType = { foo: number, bar: string, baz: boolean };
const stub: SomeClass = {
something: <SomethingType>{
foo: 1
}
}
This will break if somebody changes the library (thus we don’t lose type safety), but we have to duplicate some of the library declarations, which is not cool.
Forutnately, for situations like this, there is a lookup type supported by TypeScript. For example, in the context of our cast:
const stub: SomeClass = {
something: <SomeClass['something']>{
foo: 1
}
}
Now we explicitly bind the cast type to SomeClass#something
, which is cool!