3

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';
2
  • Do I understand your question correctly: you want a way to define a type, that would always be a union of all the values of a specific property (symbol in your case) from contents of an arbitrary array defined at compile-time somewhere else in your code? So I assume the array "definition" is changing a lot, and you want to save the time to update the type Symbols = ...definition every time? Commented Dec 18, 2021 at 9:28
  • Yes, exactly like that Commented Dec 18, 2021 at 9:49

1 Answer 1

2

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" },
]);

Playground Link

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.