2

Say I have the following object array:

const shapes = [
    { name: 'circle', color: 'blue' },
    { name: 'square', size: 42 },
    { name: 'rectangle', color: 'blue' }
];

type ShapeName = typeof shapes[number]['name']; // ShapeName is type 'string' but I would want: 'circle'|'square'|'rectangle'

I would like to have a type "ShapeName" that contains the values of the name properties of my objects. However, attempting to do so just gives me the 'string' as type. Is there a way to narrow it down to 'circle'|'square'|'rectangle'.

TsPlayground example.

1 Answer 1

1

When you define an array of objects, it only makes sense that you may add more values to it later. TypeScript assumes this is the case and you may add more objects later... which may or may not have only mentioned three values for name attribute. Also, in general, TypeScript infers that name to be a string which is most commonly what you would want a object to be inferred as. So, normally string inference is a very good idea for the most of the cases.

To tell TypeScript that this is a fixed array, you need to use Const Assertion. Which turns array literals into readonly tuples. Like this:

const shapes = [
  { name: "circle", color: "blue" },
  { name: "square", size: 42 },
  { name: "rectangle", color: "blue" },
] as const;

type ShapeName = typeof shapes[number]["name"];
// type ShapeName = "circle" | "square" | "rectangle"

Here is the TS Playground link: https://tsplay.dev/m029ow

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.