Closed
Description
Bug Report
π Search Terms
map from iterable
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about "map". The issue exhibits on the nightly playground.
β― Playground Link
Playground link with relevant code
π» Code
interface Foo {
bar: string,
baz: number
}
// no error, even though qux is not a valid property of Foo
let fooMap: Map<string, Foo> = new Map([["foo", {bar: "bar", baz: 1, qux: "qux"}]]);
// the subtractive case is caught
fooMap = new Map([["foo", {bar: "bar", qux: "qux"}]]);
// if the iterable is pulled out and typed, the error is caught. could
// also achieve this with a suffix of `as [string, Foo][]` above
let fooIterable: [string, Foo][] = [["foo", {bar: "bar", baz: 1, qux: "qux"}]]
// setting with invalid values is also caught
fooMap.set("bar", {bar: "bar", baz: 1, qux: "qux"})
// it's worth noting that primitive value types are checked as expected
let stringMap: Map<string, string> = new Map([["foo", 1]])
π Actual behavior
identifier: Map<K, V> = new Map(Iterable[K, V])
allows each V
in the iterable to have arbitrary extra properties.
π Expected behavior
identifier: Map<K, V> = new Map(Iterable[K, V])
should check that each value in the iterable is a valid V
.
Activity
MartinJohns commentedon Jun 11, 2022
Objects are not sealed. They're allowed to have arbitrary extra properties. This is unrelated to
Map<>
.You want #12936, but don't expect it to happen any time soon.
You don't provide any type arguments for your
Map<>
creation, so they're inferred based on the arguments you pass. In this case the inferred type isMap<string, { bar: string; baz: number; qux: string }>
. You assign this value to a variable typedMap<string, Foo>
, which is compatible (the type{ bar: string; baz: number; qux: string }
is compatible with the typeFoo
).You probably expect it to behave like #7782 suggests.
thisisrandy commentedon Jun 12, 2022
Right, I think I've understood. Basically, it boils down to I can do this
But not this:
The
Object literal may only specify known properties...
error was pushing me in the wrong direction on a still fuzzy (but now quite clear) point about structural typing.If I may, do the docs cover this well? I would expect to see something highlighting the object literal case e.g. on the Type Compatiblity page, but I only see two step examples.
MartinJohns commentedon Jun 12, 2022
Yep, exactly.
It very often leads to this kind of misunderstanding. It should be considered more of a linter feature, not a type-safety feature.
It's shown under "Starting out", the basic rule is mentioned there.

Otherwise:
thisisrandy commentedon Jun 12, 2022
Great, thanks for your help. I see some stuff on e.g. TypeScript for JS Programmers that deals with misspelling of properties, but I'm not sure that properly nails home the point about extra properties when the required ones are already properly specified. I'll think on where a note about this might fit on the Type Compatibility page and submit a PR.
MartinJohns commentedon Jun 12, 2022
Your example with "Foo" is literally the the second example on that page: https://www.typescriptlang.org/docs/handbook/type-compatibility.html#starting-out
thisisrandy commentedon Jun 12, 2022
No, I see that. My point was that
was not highlighted. The example
here is basically the same thing, but that may not be obvious to new users learning the core concepts, since a misspelled property doesn't necessarily feel the same as an extra property.
Here's what happened to me:
any
).Object literal may only specify known properties...
error made me second-guess myself, because naively, it seemed the same as (1).let fooMap: Map<string, Foo> = new Map([["foo", {bar: "bar", baz: 1, qux: "qux"}]]);
was fine because the logic of assignability had gotten fuzzed.Hence, I want to highlight the object literal assignment case somewhere clearly in the docs. If that's already done and I somehow missed it, please point it out, but the example you highlighted was absorbed on reading yet didn't help to keep me from confusing myself later.
Note that object literals may only specify known properties