1

How can I define foo so that i don't have to specify as Constraint for each of the array items ?

type Constraint = {
    constraint: 'required' | 'equal'
}


function bar<K extends string>(d: Record<K, Constraint[]>) {
    return Object.keys(d).reduce((a, b) => (a[b] = '', a),
                                 {} as { [key: string]: string }) as Record<K, string>
}

const foo = { apple: [ { constraint: 'required' } ] }
// Error  Type 'string' is not assignable to type '"required" | "equal"'.
const baz = bar(foo)


// Works fine
const foo2 = { apple: [  { constraint: 'required' } as Constraint ] }
const baz2 = bar(foo2)
0

1 Answer 1

3

When you type a string, TS recognizes it as a plain string, not like the 'required' literal. You can:

  1. Use the object literal directly in the function call:
const baz = bar({ apple: [ { constraint: 'required' } ] })

This way inference is preserved

  1. Declare the string as const, i.e.:
const foo = { apple: [ { constraint: 'required' as const } ] }

This lets know TS that you don't mean a generic string but the exact literal you typed. In older TS version as const is not present buy you could still use 'required' as 'required'

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.