Issue
I was trying to get this code to work:
test(a: any[]) {
let b: string[][] = [];
b.push(Object.keys(a[0]));
b.push(...a.map(e => Object.values(e)));
}
but the compiler doesn't like the b.push(...a.map(e => Object.values)));
line: "TS2345: Argument of type 'unknown[]' is not assignable to parameter of type 'string[]'. Type 'unknown' is not assignable to type 'string'"
But this same code works if I change the parameter type to test(a: { [s: string]: any }) {
which I kinda just figured out by luck.
My question(s):
- Why does it work with the weird type?
- what does that weird type even mean? it reads like gibberish to me, it's an object of keys (of type array???) which map to
any
? - when calling
a.map(e =>
it infers the type of e to bee?: any
without the weird type, and it infers ase: any
with the special signature. What doese?: any
mean?
Solution
what does that weird type even mean?
You refer to type { [s: string]: any }
, it is an index signature:
Sometimes you don’t know all the names of a type’s properties ahead of time, but you do know the shape of the values.
In those cases you can use an index signature to describe the types of possible values
(emphasis mine)
As mentioned by kelly in the question comments, it describes an object, with little information about its properties, but the values of these properties are of type any
.
Why does it work with the weird type?
Actually, it "works" if you rather type the argument a
as an array of this type:
function test2(a: { [s: string]: any }[]) { // Typed `a` as an array of objects with the "weird" type
let b: string[][] = [];
b.push(Object.keys(a[0]));
b.push(...a.map(e => Object.values(e)));
// ^? (parameter) e: { [s: string]: any; }
}
a
being an array, the compiler knows that a.map
iterates on the items of that array. And the items are objects which values are any
, which is assignable to string
.
Answered By - ghybs
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.