Skip to content
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

Weird behaviour with union types and 'strict' object literals #5237

Closed
jonnystoten opened this issue Oct 13, 2015 · 4 comments
Closed

Weird behaviour with union types and 'strict' object literals #5237

jonnystoten opened this issue Oct 13, 2015 · 4 comments
Assignees
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@jonnystoten
Copy link

I'm not sure if this a bug or by design, but it's confusing me:

interface Constraint {
  message?: string;
}

var badConstraint: Constraint = {
  messge: "rte" // errors as expected
};

var goodConstraint: Constraint | boolean = {
  messge: "rte" // I expect this to error!
};

Can anybody explain what is going on here?

http://www.typescriptlang.org/Playground/#src=interface%20Constraint%20%7B%0D%0A%20%20message%3F%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Avar%20badConstraint%3A%20Constraint%20%3D%20%7B%0D%0A%20%20messge%3A%20%22rte%22%20%2F%2F%20errors%20as%20expected%0D%0A%7D%3B%0D%0A%0D%0Avar%20goodConstraint%3A%20Constraint%20%7C%20boolean%20%3D%20%7B%0D%0A%20%20messge%3A%20%22rte%22%20%2F%2F%20I%20expect%20this%20to%20error!%0D%0A%7D%3B%0D%0A

@jonnystoten
Copy link
Author

In fact, changing boolean to Boolean fixes the problem. Is this something to do with primitives in union types?

@danquirk danquirk added the Bug A bug in TypeScript label Oct 13, 2015
@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus and removed Bug A bug in TypeScript labels Oct 14, 2015
@RyanCavanaugh
Copy link
Member

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.

@RyanCavanaugh RyanCavanaugh added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. and removed In Discussion Not yet reached consensus labels Oct 19, 2015
@RyanCavanaugh
Copy link
Member

Do we have an issue tracking the spec update?

@ahejlsberg
Copy link
Member

@RyanCavanaugh No, we don't.

@mhegazy mhegazy added this to the TypeScript 1.8 milestone Oct 20, 2015
@mhegazy mhegazy added Fixed A PR has been merged for this issue and removed Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Oct 20, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants