microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.17k stars 12.51k forks source link

Loosen property access strictness if nullish operator is being used #60560

Open sod opened 22 hours ago

sod commented 22 hours ago

🔍 Search Terms

Example:

const languages = ['de', 'en', 'fr'] as const;
type Language = (typeof languages)[number];

const fallback = 'lorem';
const customByLanguage = {
    de: 'ipsum',
} satisfies Partial<Record<Language, string>>

function getValue(language: Language): string {
    return customByLanguage[language] ?? fallback;
           // ts error: Element implicitly has an 'any' type because expression of type '"de" | "en" | "fr"' can't be used to index type '{ de: string; }'.
           //                Property 'en' does not exist on type '{ de: string; }'.(7053)
}

This error seems counter intuitive as a fallback if the property doesn't match was given via ?? fallback. Right now I need to add either typescript or javascript boilerplate to get rid of this error.

playground

✅ Viability Checklist

⭐ Suggestion

I'd expect typescript to not complain about lack of perfect key overlap if the nullish operator is being used to fallback if they key does not exist.

A bonus would be, if typescript still complained if key and object had no overlap at all, as that seems to be most likely an error.

💻 Use Cases

Now having to work with strict property access due to removal of suppressImplicitAnyIndexErrors: false in typescript 5.6

nmain commented 21 hours ago

satisfies is not the same as an inferred or explicitly annotated type. customByLanguage has the more specific type of { de: string } and no index or record signature. If you want the wider type, just use that:

Playground

const customByLanguage: Partial<Record<Language, string>> = {
    de: 'ipsum',
}