You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Weird behaviour with union types and 'strict' object literals #5237
I'm not sure if this a bug or by design, but it's confusing me:
interfaceConstraint{message?: string;}varbadConstraint: Constraint={messge: "rte"// errors as expected};vargoodConstraint: Constraint|boolean={messge: "rte"// I expect this to error!};
Obviously undesirable behavior, but it's behaving to the spec as currently written:
A source type S is considered to have excess properties with respect to a target type T if
S is a fresh object literal type, as defined below, and
S has one or more properties that aren't expected in T.
A property P is said to be expected in a type T if one of the following is true:
T is not an object, union, or intersection type.
T is an object type and
T has a property with the same name as P,
T has a string or numeric index signature,
T has no properties, or
T is the global type 'Object'.
T is a union or intersection type and P is expected in at least one of the constituent types of T.
The property messge is "expected" (in the spec sense of the word, not plain English!) in Constraint | boolean because that type "is a union [...] type", and messge is "expected" in boolean because boolean "is not an object, union, or intersection type".
So we see that the property is "expected" in the target type, and normally this would be OK because we would fail a later assignability check. But instead we successfully assign { messge: string } to { message?: string } because it has all required properties.
The proposed fix implemented in #3842 would flag this as an error. We should review that fix as it has broader good implications besides this one.
Activity
jonnystoten commentedon Oct 13, 2015
In fact, changing
booleantoBooleanfixes the problem. Is this something to do with primitives in union types?RyanCavanaugh commentedon Oct 14, 2015
Obviously undesirable behavior, but it's behaving to the spec as currently written:
The property
messgeis "expected" (in the spec sense of the word, not plain English!) inConstraint | booleanbecause that type "is a union [...] type", andmessgeis "expected" inbooleanbecauseboolean"is not an object, union, or intersection type".So we see that the property is "expected" in the target type, and normally this would be OK because we would fail a later assignability check. But instead we successfully assign
{ messge: string }to{ message?: string }because it has all required properties.The proposed fix implemented in #3842 would flag this as an error. We should review that fix as it has broader good implications besides this one.
RyanCavanaugh commentedon Oct 20, 2015
Do we have an issue tracking the spec update?
ahejlsberg commentedon Oct 20, 2015
Ryan Cavanaugh (@RyanCavanaugh) No, we don't.