'Is there a way to "extract" the type of TypeScript interface property?
Let's suppose there's a typing file for library X which includes some interfaces.
interface I1 {
x: any;
}
interface I2 {
y: {
a: I1,
b: I1,
c: I1
}
z: any
}
In order to work with this library I need pass around an object that is of exactly the same type as I2.y
. I can of course create identical interface in my source files:
interface MyInterface {
a: I1,
b: I1,
c: I1
}
let myVar: MyInterface;
but then I get the burden of keeping it up to date with the one from library, moreover it can be very large and result in lot of code duplication.
Therefore, is there any way to "extract" the type of this specific property of the interface? Something similar to let myVar: typeof I2.y
(which doesn't work and results in "Cannot find name I2" error).
Edit: after playing a bit in TS Playground I noticed that following code achieves exactly what I want to:
declare var x: I2;
let y: typeof x.y;
However it requires a redundant variable x
to be declared. I am looking for a way to achieve this without that declaration.
Solution 1:[1]
It wasn't possible before but luckily it is now, since TypeScript version 2.1. It has been released on the 7th of December 2016 and it introduces indexed access types also called lookup types.
The syntax looks exactly like element access but written in place of types. So in your case:
interface I1 {
x: any;
}
interface I2 {
y: {
a: I1,
b: I1,
c: I1
}
z: any
}
let myVar: I2['y']; // indexed access type
Now myVar
has type of I2.y
.
Check it out in TypeScript Playground.
Solution 2:[2]
To expand on the accepted answer, you can also assign the type using the type
keyword and use it in other places.
// Some obscure library
interface A {
prop: {
name: string;
age: number;
}
}
// Your helper type
type A_Prop = A['prop']
// Usage
const myThing: A_prop = { name: 'June', age: 29 };
Solution 3:[3]
Gets all values, due to keyof Colors
returning a list of all keys, which in turn gets all values of the Colors
interface
interface Colors {
white: "#fff"
black: "#000"
}
type ColorValues = Colors[keyof Colors]
// ColorValues = "#fff" | "#000"
Solution 4:[4]
Just an example of extracting a literal type from the union object type:
type Config = {
key: "start_time",
value: number,
} | {
key: "currency",
value: string,
}
export type ConfigKey = Config["key"];
// "start_time"|"currency"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ben Winding |
Solution 3 | Gabriel Petersson |
Solution 4 | James Bond |