Skip to content

Design Meeting Notes, 11/11/2020 #41505

Closed
@DanielRosenwasser

Description

@DanielRosenwasser

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions