Skip to content

Design Meeting Notes, 10/30/2020 #41342

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

Closed
DanielRosenwasser opened this issue Oct 30, 2020 · 1 comment
Closed

Design Meeting Notes, 10/30/2020 #41342

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

Comments

@DanielRosenwasser
Copy link
Member

Speed-Sensitive PRs

Definite-Assignability

#39577

  • Use a definitely-assignable relation in Material-UI
  • If it is a correctness fix, and it's only 1%... that's probably not so terrible.
    • Will manifest in codebases where people can't really even understand the types.
  • Definitely-assignable relation will never probe constraints for these.
    • Isn't this just because any is really unknown and never?
    • Maybe dual-behavior of any biting us.
      • The new relationship is about asking whether any given instantiation will break.
  • 4.2-bound if we want.

Cache Complex Union and Intersection Relations

#37910

  • We have never cached the results of relations between unions and intersections.
    • We only cache relations between constituents.
  • Could try caching all unions/intersections.
    • Made things slower in experiments.
    • Does a bunch of expensive caching - bad!
    • When relating Foo | Bar | Baz to Target, have to cache
      • Foo | Bar | Baz to Target
      • Foo to Target
      • Bar to Target
      • Baz to Target
  • Idea: as soon as we have more than 4 targets to check against, we'll cache.
    • Partial reasoning: avoiding undefined | null | T.
  • This change speeds up the compilers-with-unions test case.
  • Aside: any reason why compilers-with-unions was not in the perf suite?
    • Was crashing, should be good now.
    • Azure might be finally stable in perf numbers.
    • Can we get rid of Node 8/10?
    • And add Node 14/15
    • Perf test fast on LTS/perf test slow
  • Aside: maybe linked caches?
  • 4.2-bound!

Arbitrary Index Signatures (now that we have template string types)

#26797

  • Have this old PR.

  • Would be nice to be able to model data- and aria-.

  • We have two "kinds" of types: finite types and infinite types

    • "foo" - finite
    • "foo" | "bar" - finite
    • string - infinite
    • `aria-${string}` - infinite
  • Can imagine that mapped types on

    • finite types desugar to individual properties.
    • infinite types remain as index signatures.
  • The PR's original motivation was symbol types.

  • As a bonus, it handled string literal types and enums.

    • Those would expand out to keys.
  • Want to propose that index signatures are required to have an infinite type.

    • Including pattern-literal types like `aria-${string}`.
  • Mapped types would be the only thing that can represent keys in a higher-order manner.

    • We would not want to get into the business of { [x: T]: Type } where T is generic.
    • Can't make meaningful statements about T in those cases.
  • We want to have a view that a mapped type can have some key type that can be finite and infinite.

    • At 0-order, these types desugar as described above.
  • But we're already "equipped" to handle these.

    • Index signatures are just another structural component of the type. The hard part is actually adding the index signatures.
  • Feels like we're "ripping out the foundation" to go higher-order.

  • We can ship this with 0-order.

    • Shipping PR with forbidden higher-order is more code.
  • You need to be able to reason about constraints.

  • Follow-up

    • Type with multiple index signatures
      • Every index signature that matches, you union when reading
      • Every index signature that matches, you intersect when writing
  • We have another relationship in the PR where number is assignable to string.

    • You could build it other ways technically.
    • Could do it differently before isRelatedTo
    • But isRelatedTo does the nice logic.
  • What about

    interface Foo {
        [x: `aria-${string}`]: string;
        [x: `aria-yadda-${string}`]: boolean;
    }
    • Would be nice if we could provide a nice error message!
    • Need to be able to relate pattern types to pattern types.
    • Could imagine some set of "easier" prefix/postfix.

Partial Type Argument Inference

#26242

Out-of-time

@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Oct 30, 2020
@weswigham
Copy link
Member

@DanielRosenwasser if you're curious for a case of how higher order index types become useful, consider the validation case:

interface AriaProps<TStateProps extends "busy" | "current" | "disabled" | "grabbed" | "hidden" | "invalid"> {
    [x: `aria-${string}`]: string;
    [x: `aria-${TStateProps}`]: "true" | "false";
}

offers validation that all the possible properties produced by the second index signature are assignable to the index signature type (if the possible values overlap, which they do). Imagine we had instead written:

interface AriaProps<TStateProps extends "busy" | "current" | "disabled" | "grabbed" | "hidden" | "invalid"> {
    [x: `aria-${string}`]: string;
    [x: `aria-${TStateProps}`]: true | false;
}

the compiler would be able to warn us of our mistake - aria-busy is of type boolean, which is not assignable to the aria-${string} index signature of type string. Whereas the equivalent mapped type:

type AriaProps<TStateProps extends "busy" | "current" | "disabled" | "grabbed" | "hidden" | "invalid"> = {
    [x: `aria-${string}`]: string;
} & {
    [x in `aria-${TStateProps}`]: true | false;
}

would have no such validation, and simply produce a never upon reading each of the specified properties. There are usability reasons why generic index signatures should exist. Mapped types are definitely more powerful - the 1-to-1 correspondences they represent allow for powerful remappings of both keys, values, and modifiers, none of which are something an index signature could reasonably do without constraining when it could do them in strange ways, while index signatures play an important role in ensuring object consistency and intent - the same way overload signatures need to be consistent with the implementation.

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

2 participants