-
Notifications
You must be signed in to change notification settings - Fork 13k
Description
Search Terms
optional chain chaining required array object index access
Suggestion
The return type of any property that is accessed with the optional chaining operator should include undefined
, even when the type of the value says the property is required/non-optional. This is arguably a better reflection of the runtime behaviour, and would be useful in cases where the type does not reflect reality, and it's hard for the consumer to change that type.
Use Cases
The main use case would be index access. Today, TypeScript will assume that array/object index access will return a non-undefined value. This is not an exact reflection of runtime behaviour, but it is a conscious decision. I'd like to use the optional chaining operator to have safe access at runtime, but I'd like the returned type to reflect the possibility that the accessed value can now be undefined.
Examples
type Hit = { value: number };
type ObjWithOptionalProp = {
key?: Hit
};
type ObjWithRequiredProp = {
[x: string]: Hit;
}
const optional: ObjWithOptionalProp = {};
const required: ObjWithRequiredProp = { key: { value: 1 } };
// number | undefined
const optionalValue = optional.key?.value;
// number, could cause runtime error
const requiredValue = required.key.value;
// number (should be number | undefined)
const safeAccessRequiredValue = required.key?.value;
const hits: Array<Hit> = [];
// number, could cause runtime error
const valueFromIndex = hits[0].value;
// number (should be number | undefined)
const safeAccessValueFromIndex = hits[0]?.value;
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, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.