Closed as not planned
Description
π Search Terms
union optional property access
β Viability Checklist
- 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 isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
If a union contains multiple non-nullish values, I expect it to be ok to access the property. This would then yield the type defined by one of the union members, or undefined.
π Motivating Example
interface Person {
hands: string[]
}
interface Cat {
paws: string[]
}
declare const maybePerson: Person | undefined
const hands1 = maybePerson?.hands
// ^^^^^^ This is `string[] | undefined`
declare const creature: Cat | Person
const hands2 = creature.hands
// ^^^^^^ I expect this to be `string[] | undefined` too
// This often leads to awkward constructs with `in` checks
if('hands' in creature) {
creature.hands.map(hand => hand)
}
// where at runtime optional chaining would be fine.
creature.hands?.map(hand => hand)
π» Use Cases
I often find myself writing:
if ('key' in object) {
doSomething(object.key)
}
Or even:
if (object && 'key' in object) {
doSomething(object.key)
}
Or worse, nested constructs:
if (object && 'key' in object && typeof object.key === 'object' && object.key != null || 'nested' in object.key) {
doSomething(object.key.nested)
}
This is purely to make TypeScript happy. The following is just as safe:
if(object?.key?.nested) {
doSomething(object.key.nested)
}