I have this kind of code:
type Item = { id: number; symbol: string; }
const items: Item[] = [
{ id: 1, symbol: "a"},
{ id: 2, symbol: "b" },
];
I wonder if typescript allows to create typing that would pick all the values from items
array symbol
property, like defining this but without doing it manually:
type Symbols = 'a' | 'b';
CodePudding user response:
You cannot define the type from the actual array if the const items
declaration has a type annotation, because the type annotation will be used instead of inferring a type from the actual value. If you remove the type annotation, then you can use typeof items
to get its type, and then use indexed access to get the type of the symbol
property.
Note that you also need to use as const
to get the string literal types, otherwise they will be widened to just string
.
const items = [
{ id: 1, symbol: "a" },
{ id: 2, symbol: "b" },
] as const;
// "a" | "b"
type Symbols = typeof items[number]['symbol']
Of course, this means you now aren't checking that the array elements are actually of type Item
. To get around this, you can use the technique from this other answer; I made the type parameter S extends string
instead of T extends Item
because this way the as const
is not needed.
function checkItems<S extends string>(arr: (Item & {symbol: S})[]) {
return arr;
}
const items = checkItems([
{ id: 1, symbol: "a" },
{ id: 2, symbol: "b" },
]);