Repository: TypeScript
Issue: Design Meeting Notes, 3/19/2024
Labels: Design Notes


# Preserving attributes on reference directives

https://github.com/microsoft/TypeScript/pull/57681

* Should we strip away `preserve="true"`?
    * Would that break `.d.ts` bundlers?
        * We don't know.
    * Current declaration emitter just generates new directives.
    * We like preserving the text as a principle.
        * Not that simple though, lots of stuff already rewrites.
    * Also like the fact that you can copy/paste from a `.d.ts` and get the same behavior.
* Also, we should fix the TmLanguage files to understand the attributes.

# Reallowing `Infinity`, `-Infinity`, `NaN` as enum member names

### Background

https://github.com/microsoft/TypeScript/pull/56161
https://github.com/microsoft/TypeScript/issues/57845

- Years ago, we had a principle that enums could not have numeric names.
- no `enum E { "10" = 42 }`
- because of `enum E { "10" = 42, yadda = 10 }` which breaks the reverse mapping.
- That is, `E[10]` maps to `yadda` not `42`
- But people want to have enum members named `Infinity` or `NaN`
- Which we allowed because it was popular.
- But it could still cause problems in `enum E { Infinity = 1, yadda = 1/0 }`.
- But if you don't have any enum initialisers equal to `Infinity`, what's the problem?
- But we can't statically analyse this.
- Maybe it works for some enums though? In particular, string enums.

### Proposal

- Not really, we need a stricter rule:
	- All the values are known.
	- None of them conflict with member names.
- Or:
	- If all the values are strings.

### Discussion

- You can't actually have bare numbers -- you have to quote them.
- Reverse mappings were a mistake. We shouldn't do more.
- Would we be doing reverse mapping for string-only enums with this?
- If it's string-only, it would be OK because there would be no reverse mapping.
- If `enum E { yadda = 'yadda' }`  had a reverse mapping, it would overwrite the reverse mapping. And `Red = 'Red'` is super common.
- But wait. Reverse mappings are not a thing in string-only enums.
- The string-only rule seems fine.
- Shipping a simple revert as a 5.4 patch wouldn't be good enough, so this should wait till 5.5.
- No wait: we will revert the PR for 5.4 and ship the better rule in 5.5.

# Narrowing element accesses with non-constant expressions

https://github.com/microsoft/TypeScript/pull/57847

* Long time there's been a desire from us to narrow computed-but-effectively constant values.
* Once you've proven something about `obj[key]` and you change neither `obj` nor `key`, the type system really should understand that!
* Previously couldn't do this because typically the whole issue was that `key` was often a parameter, or varied within a loop variable.
    * But now we already have control flow analysis of parameters and `let` variables that don't actually mutate (and captured variables that don't mutate after a certain point).
* Not everything "lights up" the way you'd think.

  ```ts
  function f(obj: object, key: string) {
    if (key in obj) {
        obj[key]; // not allowed right now
    }
  }
  ```
    * Can't make this work right because we don't consider `obj` to be indexable.
    * In a sense you want `obj` to have the type `object & Record<unique typeof key, unknown>`. Really wouldn't want `obj` to be indexable with *all* `string`s, just `key` itself.
    * Manufacture a type variable/existential for `key`.
* No baseline changes or issues in the top 200.
* We saw a slight bit of slowdown in compiler-unions.
    * Mostly within the noise.