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/16/2021 #45103

Closed
DanielRosenwasser opened this issue Jul 19, 2021 · 0 comments
Closed

Design Meeting Notes, 6/16/2021 #45103

DanielRosenwasser opened this issue Jul 19, 2021 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

Generalized Index Signatures

#44604

  • Someone asked if they'd be allowed to write

    type FancyIdString = string & { __someTag: never };
    
    interface FancyIdContainer {
        [id: FancyIdString]: boolean;
        //   ^^^^^^^^^^^^^
        // This is an *intersection* with a primitive type.
    }
    • We figured: there's no reason to disallow it.
    • Reasoning: as long as you don't have a unit type or a generic, this should be permitted.
      • Unit types - we feel like we need to figure out how those tie into properties.
      • Generics - we don't have an entirely coherent model for what that means.
  • You can also have a union, provided that they consist of "infinite" primitive types, tagged intersections.

    // Works!
    interface Foo {
        [id: string | number | (symbol & { __fancyTag: never })]: boolean;
    }
  • Non-union enums are technically unbounded - you can assign any number to them - should we allow them?

    enum E {
        A = +0,
        B,
    }
    
    interface Foo {
        [id: E]: boolean;
    }
    • Kind of iffy.
    • We also don't like people to use non-union enums.
    • It is strange because you have the same "branding" issue between enums and tagged primitives.
      • Well, there are no branded literals.
      • But does the brand disappear in the base type?
  • How does keyof work on branded index signatures?

    type FancyIdString = string & { __someTag: never };
    
    interface FancyIdContainer {
        [id: FancyIdString]: boolean;
    }
    
    type FancyKeys = keyof FancyIdContainer; // FancyIdString
    
    type ReconstructedFancy = Record<FancyKeys, boolean>; ?
    • And also, how do we handle the interplay of branded index signatures and properties? Do we detect conflicts?
  • How does the following work?

    type BrandedProp1 = "prop" & { __brand__: void };
    type BrandedProp2 = "prop" & { __brand2__: void };
    
    type Q = Record<BrandedProp1 | BrandedProp2, number>;
    • This gives you just { prop: number }...right?
    • No.
    • Empty object.
    • Wat?
    • Okay, but then keyof is perfectly preserved as BrandedProp1 | BrandedProp2
    • The types "look" like they're working, but there's loss of fidelity in some places.
  • Can we just omit support for branded index signatures?

    • Want to intersect several different template string types.
    • Don't need to do this to ship in 4.4.
    • But highly desired.
  • Making this work with property names, and straightening out the inconsistencies mentioned above, could be tough.

    • There's a lot of internal complexity in the compiler around fetching names of properties
      • In-source names
      • Symbolic names
      • Literal-generated names
    • Lots of legitimate use-cases to keep in mind though, not always about working with types.

Preserving Imports

#44137 (comment)
#44619

  • We had this idea for importsNotUsedAsValues: preserve-exact as a thing that just says "don't touch the imports"
    • Is this the right flag?
    • Sounds like a jumble of words anyway.
    • That was not the right flag for this.
    • importsNotUsedAsValues is about the entire import statement.
  • Strawperson name: noErasingImportedNames
    • Under isolatedModules: false, TypeScript can use information across files to determine whether it needs to drop an import.
    • Under isolatedModules: true, TypeScript will always preserve an import, and detect/error if it's going to cause runtime issues.
  • Outside of isolatedModules, this has (useful) behavior that doesn't exactly do what the flag says it does.
    • It's more type-driven to some extent - but we already do this outside of isolatedModules.
  • What would we recommend to people?
    • Depends!
  • Want to understand the use-cases a bit better for Svelte and Vue

Renaming strictOptionalProperties

#44604

@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Jul 19, 2021
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

1 participant