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

Omnibus fresh object subtype reduction / contextual type issue #19236

Closed
RyanCavanaugh opened this issue Oct 16, 2017 · 4 comments
Closed

Omnibus fresh object subtype reduction / contextual type issue #19236

RyanCavanaugh opened this issue Oct 16, 2017 · 4 comments
Assignees
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@RyanCavanaugh
Copy link
Member

// Problem 1: Error spans are useless in contextually-typed array/object literal cases
type Kind = 'foo' | 'ball';
// Error is on declared identifier instead of bad element
const ka: Kind[] = [
    'foo', 'ball', 'xxxx', 'foo', 'ball'
];
// Error is on declared identifier instead of bad key
const ko: { [s: string]: Kind } = {
    'x': 'foo',
    'y': 'xxxx',
    'z': 'foo'
};

// Problem 2: Subtype reduction screwage in the presence of contextual type
type OK = { ok?: boolean };
// No error??
const o1: OK = '??' ? { ok: 'wat' } : { };

// Problem 3: Aliased subtype reduction screwage
const obj = '??' ? { ok: 'wat' } : {};
// No error??
const o2: OK = obj;

Hypotheses:

  • Computing a union type in the presence of a contextual type is a waste of time
    • If we do this, we can produce good error spans?
  • Unioning { x: T } with a fresh { } should produce { x?: T }
  • Unioning a fresh object literal with { } should do something special
  • Unioning fresh { x: number, y: number } | { x: number } should produce { x: number, y?: number}
@RyanCavanaugh RyanCavanaugh added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript labels Oct 16, 2017
@zpdDG4gta8XKpMCd
Copy link

pardon me, can we keep { x: T } | {} as it is: { x: T } | {} ? or what is the way to encode an empty (no properties) object?

@ahejlsberg
Copy link
Member

@Aleksey-Bykov The issue is that { x: T } | {} is too weak. Anything is assignable to it because anything is assignable to {}. The idea is to instead infer the type { x: T? } which says that if there is an x property it must be of type T.

@zpdDG4gta8XKpMCd
Copy link

it's sad that there is no place for a true empty object {} which doesn't accept any properties

we use it as yet another unit type in addition to null and undefined and []

@zpdDG4gta8XKpMCd
Copy link

so the problem here is the syntax {} is overloaded with semantics:

  • {} should mean an object with no properties as it literally stands
  • {} should mean a top type assignable from anything
    we need a way to distinguish the two Exact Types #12936

@mhegazy mhegazy added this to the TypeScript 2.7 milestone Oct 30, 2017
@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 30, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 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

4 participants