Issue
there is a riddle about Typescript I cannot understand:
const randomFn = (arg: Record<string, unknown>): string => 'kappa'
export type Values = {
key: string;
};
const values: Values = {
key: 'kappa'
}
const { ...spread } = values;
randomFn(values)
randomFn(spread) // produce Index signature for type 'string' is missing in type '{ transaction: string; }'.(2345)
Why is Typescript producing errors for spread object when in my understanding it typing should be the same. If we inspect the object in playgroud it is exactly the same for TS compiler. Both original and spreaded.
TS version 4.5.4. Reproduction in Type Script Playground
EDIT: also doing double spread to make it work again .
randomFn({...spread}) // NO error
Solution
This is the result of a design limitation of TypeScript, see microsoft/TypeScript#42021 for details. When you use a rest element in an object destructuring assignment, TypeScript unfortunately does not copy an index signature into the type of the new variable. Nor does it allow the variable to have an implicit index signature (although I'm not sure why).
Your Values type alias is allowed to have an implicit index signature (if you made it an interface then it wouldn't either, see microsoft/TypeScript#15300), so it is considered assignable to Record<string, unknown> (which is equivalent to {[k: string]: unknown}, a type with a string index signature). But spread, as a rest-destructured variable, is not, and therefore it fails.
You noticed that doing a second rest destructuring does work, so presumably there's something weird about how object types get marked to allow or disallow implicit index signatures. This is also noted in microsoft/TypeScript#42021, although without explanation.
So unfortunately there's not a very satisfying answer to be had right now, unless more activity happens in microsoft/TypeScript#42021.
Answered By - jcalz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.