Reputation: 1023
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)
Upvotes: 1
Views: 97
Reputation: 3501
When you type a string, TS recognizes it as a plain string
, not like the 'required'
literal. You can:
const baz = bar({ apple: [ { constraint: 'required' } ] })
This way inference is preserved
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'
Upvotes: 3