Skip to content

Use of the optional chaining operator should always be reflected in type #35139

@dgieselaar

Description

@dgieselaar

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;

Playground

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.

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