Skip to content

Allow inferred object literal optional propertiesΒ #62944

@rtcpw

Description

@rtcpw

πŸ” Search Terms

"object literal", "object literal optional properties", "inferred object literal optional properties"

βœ… Viability Checklist

⭐ Suggestion

With exactOptionalPropertyTypes, it becomes quite important to mark each property as optional via ?, | undefined, or both. We need an ability to mark object literal properties as optional.

πŸ“ƒ Motivating Example

The inferred object literals do not allow marking a specific property as optional. For example, the literal obj:

function getValue1(): string {
    return 'hello world';
}

const seed = Math.random();

function getValue2(): number | undefined {
    return seed > 0.5 ? 1 : undefined;
}

const obj = {
    prop1: getValue1(),
    prop2: getValue2(),
};

infers this type:

{
    prop1: string;
    prop2: number | undefined;
}

But there is no way to hint to the type inferer to mark the prop2 as optional. What I want is this inferred type:

{
    prop1: string;
    prop2?: number | undefined;
}

I propose the following syntax to achieve this:

const obj = {
    prop1: getValue1(),
    prop2?: getValue2(),
};

πŸ’» Use Cases

  1. What do you want to use this for?

I use the excellent zod library, and having the ability to create object literals with optional properties within transforms would allow me to create the types exactly how I need them to be while using the exactOptionalPropertyTypes option.

  1. What shortcomings exist with current approaches?

It is currently not possible to conveniently create inferred optional properties without discarding the undefined union type from the property as well. Eg. this workaround will add the optional flag to the property, but it will discard the undefined union type:

const obj = {
    prop1: getValue1(),
    ...(getValue2() != null ? { prop2: getValue2() } : {}),
};
  1. What workarounds are you using in the meantime?
const obj = {
    prop1: getValue1(),
    ...(getValue2() != null ? { prop2: getValue2() } : { }),
    ...(getValue2() == null ? { prop2: undefined } : { }),
};

This is obviously less than ideal due to having to repeat the code twice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions