-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type containing intersection of object with optional property allows unsafe assignment #22255
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Is this is similar problem? const a: { y: string, x: number } = { y: 'hello', x: 4 };
const b: { y: string } = a;
const c: { y: string; x?: boolean } = b;
const d: boolean | undefined = c.x; // No error. c.x is 4. TypeScript has the following assignment compatibility rule:
also writen as: M is an optional property and S has no apparent property of the same name as M. where S is the type on the left hand side (source of the assignment). This is not sound in general. According to the definition of apparent members I think yours should still be rejected, but mine should not. When one of more constituent types of I have an apparent property named N, I has an apparent property named N of an intersection type of the respective property types. |
This one is working as intended, even if it is unfortunate. It is generally the case that a type The core dilemma really is that we say (a) a type |
Do you think it would ever be suitable to have some stricter mode that always applies rule (a) before (b), so that it's not possible to forget properties then re-add them at different types in the same compatibility test. In the strict mode, if users still wanted the original behaviour they could factor through an intermediate type in two coercions. |
Not it a consistent manner. Given an intersection |
Thanks for the explanation I'll close this then. Even in the case where I ran into this it was easy to work around via adding the extra layer of mapped type so it was not very much of an inconvenience. |
@ahejlsberg Thanks for the explanation--I overlooked generics. I think I'll just have to concede that my view on strictness here is not pragmatic.
For instance, this would not be odd to me for the same reason that
I agree this is undesirable, but I think the rules currently prevent things might be desirable such as:
That applies in some cases but not others:
A stricter rule would be consistent in that (1) holds for all types when the assignment from T to S does not involve adding adding optional properties, and when the assignment does add properties then the subtyping relation may not remove said properties, also applying equally to all types. Anyway the issue is closed; I think there is enough evidence to suggest that any stricter rule would not be suitable in general. |
TypeScript Version: 2.8.0-dev.20180228
Search Terms:
Code
Expected behavior:
Error for
example1
.Actual behavior:
No error for
example1
. The other examples are working as expected I just added them for context.Playground Link:
https://www.typescriptlang.org/play/#src=declare%20const%20a%3A%20%20%7Bx%3F%3A%20string%7D%20%26%20%7By%3A%20any%7D%0Aconst%20example1%3A%20%7Bx%3F%3A%20number%2C%20y%3A%20any%7D%20%3D%20a%20%2F%2F%20Expected%20error%20but%20didn't%20get%20one%0Aconst%20example2%3A%20%7Bx%3F%3A%20number%7D%20%3D%20a%20%2F%2F%20Got%20a%20TS2322%20error%20as%20expected%20if%20the%20y%20parameter%20is%20excluded%0A%0Adeclare%20const%20b%3A%20%20%7Bx%3F%3A%20string%2C%20y%3A%20any%7D%20%0Aconst%20example3%3A%20%7Bx%3F%3A%20number%2C%20y%3A%20any%7D%20%3D%20b%20%2F%2F%20Now%20get%20a%20TS2322%20error%20as%20expected%0A%0Atype%20MappedIdentity%3CT%3E%20%3D%20%7B%20%5BK%20in%20keyof%20T%5D%3A%20T%5BK%5D%20%7D%0Adeclare%20const%20c%3A%20MappedIdentity%3C%7Bx%3F%3A%20string%7D%20%26%20%7By%3A%20any%7D%3E%0Aconst%20example4%3A%20%7Bx%3F%3A%20number%2C%20y%3A%20any%7D%20%3D%20c%20%2F%2F%20TS2322%20error%20as%20expected%20when%20going%20through%20identity%20mapping
Related Issues:
There are obviously a lot of issues about unsafe assignments but after looking through all the search terms above and checking the issues that have titles that sounded related, the only one that really seemed similar was #19927 which I opened a few months ago.
This case seems different to me though (specifically because of
example2
above, which is the most similar to #19927 but has different behavior) which is why I'm creating the separate issue. But they're both about unsafe assignments that are allowed when there are weird combinations of optional properties and intersections so maybe there is a single root cause behind them both.The text was updated successfully, but these errors were encountered: