Skip to content

Design Meeting Notes, 10/10/2016 #11505

Closed
@DanielRosenwasser

Description

@DanielRosenwasser

Control Flow Analysis for Array Construction (#11432)

AH: Improving furthur on un-annotated initializers, we have expanded our logic to "evolve" the type of an empty array.

function f1() {
    let x = [];
    x; // never[]
    x[0] = 5;
    x; // number[]
    x[1] = "hello";
    x; // (number | string)[]
}

This evolution "stacks".

function f1() {
    let x;
    x; // any
    x = [];
    x; // never[]
    x[0] = 5;
    x; // number[]
    x.push("hello");
    x; // (number | string)[]
    x = 10;
    x // number
}

Junctions have interesting cases with constructions of exclusive types.

function f1() {
    let x;
    if (/*...*/) {
        x = [];
        x[0] = 5;
    }
    else {
        x = [];
        x.push("hello");
    }
    return x;
}

Subset Types (#11233)

Name is up for debate & bikeshedding.

interface State {
    name: string;
    length: number;
    foo?: number;
}

function update(updates: subset State) {
    // ...
}

update({name: "bob"});      // okay
update({name: 100});        // error
update({glorb: "florb"});   // error: excess property

function setState<T>(state: T, updates: subset T) {
    // ...
}

let s = { a: 10, b: 20};
setState(s, { a: 10 });
setState(s: { c: 100}); // error: excess property

Problem is that users excess property checking can be lost through intermediate assignments

Generics

What happens when you have a partial type parameter in a function?

function doSomething<T>(x: T) {
    let y: subset T;

    // (1) - okay
    y = x;

    // (2) - okay
    x = y;

    // (3) - Huh!?
    y = { surprise: "this works!" };
}

Resolution: Only things that are assignable to subset T are

  1. T
  2. subset T
  3. any.

What about this?

function doSomething<T extends { foo: string }>(x: T) {
    let y: subset T = null;

    // (1) - ???
    y = { foo: "hello" };
}

Resolution: Not allowed.

Why?

We can be more conservative later, but if you think about it from the perspective of no constraint (where it's implicitly {}), then really any type should be assignable to subset T in those scenarios.

Non-properties

Index Signatures

interface Foo {
    [x: string]: string;
}

// Effectively the same as '{ [x: string]: string | undefined }'.
let qq: subset Foo = {};
qq["blah"] = "okay?";

Name of

Resolution: subset

Extensibility (#10159)

More of a meta discussion.

Uses

  1. Templating systems that can work with the type system.
  2. Arbitrary buffers
  3. Allowing linting tools to hook into diagnostic reporting.

All are in some way related to language service.

Pros

Great tooling, allows different libraries & frameworks to give an augmented experience.

Cons

  • Coordination can be complex, user experience is at risk.
  • Need to provide way of diagnosing extensions & sandboxing.
  • API surface area increases, must be maintained.
    • Can't break extensions once they ship.

Status

Unresolved.

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