let a : any;
let m = new Map<any, any>(Object.keys(a).map(prop => ([prop.x, prop.y])));
with esnext
target produces the error
file: 'file:///c%3A/GIT/MainLine/members/src/tasks/list/decTest2.ts' severity: 'Error' message: 'Argument of type 'any[][]' is not assignable to parameter of type 'Iterable<[any, any]>'. Types of property '[Symbol.iterator]' are incompatible. Type '() => IterableIterator' is not assignable to type '() => Iterator<[any, any]>'. Type 'IterableIterator' is not assignable to type 'Iterator<[any, any]>'. Types of property 'next' are incompatible. Type '(value?: any) => IteratorResult' is not assignable to type '(value?: any) => IteratorResult<[any, any]>'. Type 'IteratorResult' is not assignable to type 'IteratorResult<[any, any]>'. Type 'any[]' is not assignable to type '[any, any]'. Property '0' is missing in type 'any[]'.' at: '4,27' source: 'ts'
which is strange because
let m2 = new Map<any, any>([[1, 2], [2, 3], ['a', 'b']])
compiles fine. What do I need to add to the first sample to get it to compile?
Note that I do know that
let m2 = new Map<any, any>(<any>[[1, 2], [2, 3], ["a", 'b']])
will also fix it, but I'd like to understand why this errors out, and see if there's a more decent fix.
TSConfig sourceMap. Enables the generation of sourcemap files. These files allow debuggers and other tools to display the original TypeScript source code when actually working with the emitted JavaScript files. Source map files are emitted as .js.map ...
The mapping in "paths" is resolved relative to "baseUrl". Hence, our configuration should be as follows: When we use this configuration, TypeScript compiler “jumps” up a directory from the src directory and locates the node_modules directory.
Transpile TypeScript into JavaScript #. Step 1: Create a simple TS file #. Open VS Code on an empty folder and create a helloworld.ts file, place the following code in that file... Step 2: Run the TypeScript build #. Step 3: Make the TypeScript Build the default #. Step 4: Reviewing build issues #. ...
We can empty an entire Map by using the clear method in typescript map. We use the for-of looping operator to loop over entries in a Map in typescript. The keys method returns the keys in the map as an array which we can loop over using for-of like so.
The problem is that TypeScript doesn't know for sure if your array is meant to be a tuple or a plain array in that context. Type argument inference tries to only use its arguments as inference sites.
As a result, when calling map
, it doesn't draw an inference from the type of the parameter of new Map<any, any>(...)
) to the return type of map
.
TypeScript 2.4 is making some changes in this direction, and your specific scenario was brought up. Discussion and progress on the issue itself can be tracked here.
As a workaround, you can write an explicit return type
(prop): [any, any] => [prop.x, prop.y]
or you can give map
an explicit type argument
Object.keys(a).map<[any, any]>(...)
Note that in either case, TypeScript catches the error that x
and y
are not valid properties on string
s.
The key here is the type of what your map
callback function is returning.
prop => [prop.x, prop.y]
TypeScript doesn't automatically infer tuple types from array literals like the array you're returning—it'll instead assume a regular array type (in this case, any[]
) which means your call to map
will return an array of that type (in this case, any[][]
).
The Map
object constructor, however, is expecting an array of a specific tuple type. In this instance, it'll be looking for an array or iterable of [any, any]
(we'll call that [any, any][]
for simplicity).
Since TypeScript doesn't automatically infer the tuple type from the array you're creating in map
, the quickest way to satisfy the typechecker is to specify the return value of the function to show that you intend it to be used as a tuple:
(prop): [any, any] => [prop.x, prop.y]
With the callback's return value type being explicitly set, map
will return a value of type [any, any][]
which satisfies the Map
constructor.
From the looks of it the compiler simply cannot infer the expected type for map<U>
if you set it explicitly, its fine:
let a: any;
let b = Object.keys(a).map<[any, any]>(key => [key, a[key]]);
let m = new Map<any, any>(b);
the problem is that it is giving up and returning any[][]
which is invalid for the expected type tuple: [any, any][]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With