Typescript DeepPartial/Partial без undefined

Рейтинг: 1Ответов: 1Опубликовано: 25.02.2023

У меня есть тип testType:

type testType =
    {
        property1: string;
        objectProperty:
        {
            test0: number;
            test1: boolean;
            test2: string;
        };
    };

И я хочу получить тип, в котором все свойства объекта будут не обязательные. Т. к. обычный Partial нам не подходит из-за вложенного объекта, я нашел DeepPartial:

type DeepPartial<T> = T extends object ?
    {
        [ P in keyof T ]?: DeepPartial<T[ P ]>;
    } : T;

В итоге мы получаем код:

export type DeepPartial<T> = T extends object ?
    {
        [ P in keyof T ]?: DeepPartial<T[ P ]>;
    } : T;

type testType =
    {
        property1: string;
        objectProperty:
        {
            test0: number;
            test1: boolean;
            test2: string;
        };
    };

type testTypePartial = DeepPartial<testType>;
/*
{
    property1?: string | undefined;
    objectProperty?: 
    {
        test0?: number | undefined;
        test1?: boolean | undefined;
        test2?: string | undefined;
    } | undefined;
} 
*/

Но тут я осознаю, что я смогу передать свойство со значение undefined, но мне этого не нужно. Мне скорее нужно получить объект, где должно быть свойство с изначальным типом либо его вообще не должно быть. Как это можно реализовать?

И я так понимаю, что получится очень много перечислений типов, что не есть хорошо.
Я ожидаю следущее:

// Правильно
const test0: testTypePartial =
{
    property1: "value"
};

// Неправильно
const test1: testTypePartial =
{
    property1: undefined  // Тип "undefined" не может быть назначен для типа "string". ts(2322)
};

Ответы

▲ 1Принят

Надо в настройках тайпскрипта (tsconfig.json) включить exactOptionalPropertyTypes.

Playground.