-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new Map(Iterable[K, V]) with complex value type V can have arbitrary extra properties on each V #49500
Comments
Objects are not sealed. They're allowed to have arbitrary extra properties. This is unrelated to You want #12936, but don't expect it to happen any time soon.
You don't provide any type arguments for your You probably expect it to behave like #7782 suggests. |
Right, I think I've understood. Basically, it boils down to I can do this interface Foo {
bar: string,
baz: number
}
const fooLike = { bar: "bar", baz: 1, qux: 1 };
const foo: Foo = fooLike; But not this: const badFooLiteral: Foo = { bar: "bar", baz: 1, qux: 1 }; The 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. |
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. |
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. |
Your example with "Foo" is literally the the second example on that page: https://www.typescriptlang.org/docs/handbook/type-compatibility.html#starting-out interface Foo {
bar: string,
baz: number
}
const fooLike = { bar: "bar", baz: 1, qux: 1 };
const foo: Foo = fooLike; interface Pet {
name: string;
}
let pet: Pet;
// dog's inferred type is { name: string; owner: string; }
let dog = { name: "Lassie", owner: "Rudd Weatherwax" };
pet = dog; |
No, I see that. My point was that // Object literal may only specify known properties, and 'qux' does not exist in type 'Foo'
const badFooLiteral: Foo = { bar: "bar", baz: 1, qux: 1 }; was not highlighted. The example interface User {
name: string;
id: number;
}
const user: User = {
username: "Hayes",
// Type '{ username: string; id: number; }' is not assignable to type 'User'.
// Object literal may only specify known properties, and 'username' does not exist in type 'User'.
id: 0,
}; 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:
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. |
Bug Report
π Search Terms
map from iterable
π Version & Regression Information
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
identifier: Map<K, V> = new Map(Iterable[K, V])
allows eachV
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 validV
.The text was updated successfully, but these errors were encountered: