Skip to content

Design Meeting Notes, 11/11/2020 #41505

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

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.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

1 participant