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, 6/5/2020 #38951

Closed
DanielRosenwasser opened this issue Jun 5, 2020 · 1 comment
Closed

Design Meeting Notes, 6/5/2020 #38951

DanielRosenwasser opened this issue Jun 5, 2020 · 1 comment
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

unknown annotation on catch clause variables

#36775

  • If you can write unknown, can you write any?
    • Yes
  • Can you write never?
    • No, you can't guarantee that nothing will ever throw.
  • Types that resolve to unknown and any?
    • Sure

Placeholder Types

#31894

Thanks to @orta for helping with the notes here

Background: we've talked about placeholder types, the idea is you need to talk about a type which exists even though you don't know all of the contents before you use it.

Normally that's an issue WRT conflicting environments. You can do an interface but they have flaws like

interface Buffer {}

let x: Buffer

function foo(x:Buffer) {}

// all work though :(
foo(1)
foo("")
foo({})

A proposal:

placeholder type Foo

which is verbose for searchability, it can be declared but not assigned

placeholder type Foo

const a: Foo = 12 // error

Fails! You need to have an implementation

placeholder type Foo

type Foo = number

const a: Foo = 12

Now it's legal.

You can constrain the placeholder:

placeholder type Foo extends string

// fails
const a: Foo = 12

and you can have many constraints which are intersected:

placeholder type Foo extends string
placeholder type Foo extends number

// fails because foo is a never
const a: Foo = 12
  • Is this bascially an existential type? Is this a new type kind

Ish. It needs to act like a type param in assignability. Needs to be able to do the same circularity checking for type aliases and type parameters.
Has to have all the same interface validation too. Because it does all that, it needs to anticipate being a class, interface or type - it needs to encode a lot of different data.

So I opted for a new 'type kind' - which is

  • What's TODO?

Generics is tricky (higher kinded types ish)

placeholder type foo<T> extends string

Could this be figured out at bind time? And at check time we know if there's an implementation. Can it be resolved before figuring out where it is about it?

  • That's already what it does.

Foo isn't higher kinded, but once resolved it is - you can know whether there was an implementation or not post bind-time.

placeholder type Foo<T> extends { x: T }

If an implementation exists, you can discard all placeholder resolution logic and just perform consistency checks on the declarations.

Lots of people want to bikeshed on the name placeholder - maybe defer?

Q: How does this relate to placeholder types for values

Think some of those ideas could be re-used

placeholder const x

if (typeof x === "")

Or examples:

placeholder type SetTimout

declare const coolSetTimeour: NodeSetTimeout
declare const coolSetTimeour: DOMSetTimeout

Q: What kind of problems does this solve?

Lots of deps have a hard dep on Node.js types (often for Buffer) - instead of including all of Node.js (and changing your entire environment)
then you can instead declare "I use buffer" and your package does not need to include all of types for environment

placeholder type Buffer;
placeholder type Map<K, V>;
placeholder type HTMLElement;

are real-world cases across ImmutableJS, Vue, etc.

Q: How do we deal with a world where people keep moving things into the global scope, can I do a placeholder module?

e.g. something like?

placeholder module 'showdown' {
  export function parse(): ShowdownDocument;
  export placeholder type ShowdownDocument;
}

You also need placeholder values (this module has this value which has this type). Are we making higher order namespaces?

// Maybe?
placeholder type "buffer".Buffer 

Note: Buffer is both exported by node global and a buffer types, and the global is deprecated

Q: Do We want a way to assert a module has a specific type?

Idea: We want to declare a type alias which defaults to something. Today you can only have one, but it'd be great to have multiple.

  • but it's not a type alias, it has to account for more than just that

Some of the implementation details for this can be done offline.

Variadic Tuples

#5453

  • Current work: can now have any number of generic placeholders in the middle of a tuple

    type Foo<T extends any[]> = [number, ...T, string];
  • If you instantiate one of these with an un-fixed array type, the type unions with subsequent element types to create a rest type.

    type Bar = Foo<boolean[]>; // [number, ...(string | boolean)[]]
  • With some inference smarts, can now write

    type First<T extends readonly[]> = T[0];
    type DropFirst<T extends readonly[]> =
      T extends [...any[], infer U] ? U : never;
  • Inference rules make sense, but get hairy.

    • More to come here.

Open String Union Types

#29729

interface Options {
    borderColor: "black" | "red" | "green" | "blue" | "yellow" | string;
}
  • People just want completions, but you can assign any string.
  • But what about
    • boolean | number | any - same deal?
    • keyof
  • Very similar idea to proeprties + index signatures. Nonsensical, but keyof on that thing makes sense.
  • If it's completions-only, maybe JSDoc?
  • But how do you preserve type identity?
    • string is the same string no matter where you use it.
    • There is no special "string, but this one with auto-complete"
  • We have something pertinent where we stop doing subtype reduction in certain cases.
    • We could avoid doing subtype reduction until comparison time?

out of time

@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Jun 5, 2020
@treybrisbane
Copy link

@DanielRosenwasser Very keen for this tuple work! 😍

Also, the point about placeholder types being higher-kinded-ish has definitely peaked my interest! Some notion of higher-kinded types could address a few of TypeScript's limitations, including things like #32523 and #26242. I'm not sure if placeholder types would help in either of those two cases specifically, but it's nice to see some thinking in the higher-kinded area. 🙂

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

3 participants