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

Design Meeting Notes, 11/11/2020 #41505

Closed
DanielRosenwasser opened this issue Nov 11, 2020 · 0 comments
Closed

Design Meeting Notes, 11/11/2020 #41505

DanielRosenwasser opened this issue Nov 11, 2020 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

Conditional Spread is More Prone to Losing | undefined

#41418

declare let bool: boolean;

const obj = {
  ...bool && { x: 'x' },
  ...bool && { y: 'y' },
};

const x: string = obj.x;
obj.y = undefined;
  • After we added conditional spreading behavior after the RC, we saw that it was more prone to being found.
declare let r: { [key: string]: number };

let fromExpression = { ...bool && { x: 3 } };
r = { ...fromExpression }; // Ok

declare let fromAnnotation: { x?: number };
r = { ...fromAnnotation }; // Error: Type 'undefined' is not assignable to type 'number'.
  • Type from x includes undefined in fromAnnotation.
  • The behavior we're seeing right now is what's in the RC.
  • The behavior is not new - it existed, it was just harder to observe.
declare let z: { a: string } | {};
const zz = { ...z }
  • Have there been any other issues filed on this in the past?
  • First, it is strange that an optional property is not assignable to an index signature.
  • It is unclear if it's actually undefined or missing.
    • These are "past sins" that we can't correct.
    • Co-mingling undefined means we can't do anything.
  • Maybe one rule: allow undefined to be written to an index signature.
  • We also just have a bug - you cannot have properties that don't have undefined in their type.
  • Should we allow optional properties to be assigned to an index signature?
  • General agreement - we had some sense of urgency because we thought it became MUCH more observable - but probably just only a little bit more observable.
const obj2 = { m: Math.random() > 0.5 ? undefined: "" };
const q: { m?: string } = obj2;
const a: { [s: string]: string } = q;
if ("m" in a) {
    a["m"].toUpperCase();
}
  • With the optionality rule, obj2 is not assignable to a, but q is assignable to a.
    • Non-transitivity has always been the case ¯\_(ツ)_/¯
  • Continue next week?

Backing out resolve Changes

#41497

  • The assignability issue is really closer to a bug fix.
    • The Did you forget to include 'void' in your type argument to 'Promise'? errors aren't related to these.
  • There's some conflation in the concerns.
  • "void reform.
  • How common was the parameter optionality issue?
    • Pretty common.
    • It's been this way for years.
  • We have complaints about why isn't it stricter?
    • Most feedback is positive - they're happy to be broken.
  • We made trailing void optional just to be ready for this fix.
  • Tried to solve this with new inference, but causes more problems than it's worth.
  • Everything that's "more elegant" is very messy and counter to our inference strategies.
  • 4.1 is otherwise not that breaky, and this is pretty mechanical.
  • Pre-seed some StackOverflow question about it to help users find the right answer?
  • It seems like overall, we want to keep this in.

abstract Constructor Types

#36392

  • Allows us to prefix construct signatures with the abstract keyword.
  • abstract new () => any.
  • Today in lib.d.ts, we have Constructor.
    • Today, you can write a mixin using the Constructor type.
    • But Constructor doesn't allow abstract classes, so you can't write a mixin on abstract classes.
  • It is okay to assign a concrete constructor to an abstract constructor.
  • It is not okay to assign an abstract constructor to a concrete constructor.
  • When extending from an abstract constructor, you must declare it to be abstract.
    • You need to do this because there's no way to know which members are or are not getting implemented.
    • The construct signature doesn't signal which instance-side members are abstract.
  • Kind of like readonly - promising you won't do something with the type (i.e. construct it directly).
  • Out of time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

1 participant