- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.1k
Closed
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Description
Generalized Index Signatures
- 
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 numberto 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 keyofwork 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 keyofis perfectly preserved asBrandedProp1 | BrandedProp2
- The types "look" like they're working, but there's loss of fidelity in some places.
 
- This gives you just 
- 
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.
 
- There's a lot of internal complexity in the compiler around fetching names of properties
Preserving Imports
- We had this idea for importsNotUsedAsValues: preserve-exactas 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.
- importsNotUsedAsValuesis 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.
 
- Under 
- 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.
 
- It's more type-driven to some extent - but we already do this outside of 
- What would we recommend to people?
- Depends!
 
- Want to understand the use-cases a bit better for Svelte and Vue
Renaming strictOptionalProperties
Metadata
Metadata
Assignees
Labels
Design NotesNotes from our design meetingsNotes from our design meetings