8000 Record from noUncheckedIndexedAccess: false can't be expressed when noUncheckedIndexedAccess: true · Issue #48917 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content
Record from noUncheckedIndexedAccess: false can't be expressed when noUncheckedIndexedAccess: true #48917
Closed
@safareli

Description

@safareli

Suggestion

Like with ways for adding and removing optionality form properties ?/- there seams to be a need to remove the special undefinedness of properties introduced in noUncheckedIndexedAccess:true

🔍 Search Terms

noUncheckedIndexedAccess Record Array

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

📃 Motivating Example

With noUncheckedIndexedAccess:false we have a notion of Record that defines values, for all the possible properties. In practice there are not many actual values like that. Point ofnoUncheckedIndexedAccess:true was to automatically add | undefined type to result of property access so we are more type-safe automatically.

The main TypeSafe use-case for the records which do have value for any possible key are Proxies. And looks like we have lost a way to express the those properly with noUncheckedIndexedAccess:true

💻 Use Cases

Imagine

const val = new Proxy<{[k in string]: string}>({}, {
  get: (_, p) => p.toString().toUpperCase()
});

const foo = val.foo

with noUncheckedIndexedAccess:false, typer of foo is string tho with noUncheckedIndexedAccess:true, foo has type: string | undefined which is not correct. here we know 100% that any value we read from val via property access, must be string, but it can't be expressed using Typescript when noUncheckedIndexedAccess:true.

We can visualize what we lost using this table:

| noUncheckedIndexedAccess:false | Record<string,string> | Record<string,string | undefiend> | 
| noUncheckedIndexedAccess:true  | _____________________ | Record<string,string>             |

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0