Можно ли заставить все дополнительные свойства интерфейса машинописного текста принимать значение null?

У меня есть интерфейс, определенный как

interface IExample {
  property1: string;
  property2: number;
  property3?: number;
  property4?: string;
}

Как заставить все необязательные свойства принимать значение null? Я не хочу добавлять null к каждому дополнительному свойству.

Я пытался создать этот тип, но это не работает

  type SetOptionalKeysNullable<T> = {
    [K in keyof T]: T[K] extends undefined ? undefined | null : T[K];
  };

Видели это? stackoverflow.com/questions/68713907/…

Dai 29.08.2024 08:16

Для обнаружения необязательных свойств требуется нечто большее, чем просто проверка undefined. См. ссылку на эту игровую площадку. Соответствует ли это вашим потребностям? Если да, то я напишу ответ или найду подходящий дубликат. Если нет, то что мне не хватает?

jcalz 29.08.2024 15:19

@jcalz Спасибо, это то, чего я в идеале хотел. Работает так, как ожидалось. Просто интересно, можем ли мы сделать его рекурсивным, чтобы вложенные поля вели себя одинаково.

Deepak Gupta 29.08.2024 16:06
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
3
50
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете обратиться к исходному коду Partial:

type Partial<T> = {                 
     [P in keyof T]?: T[P];              
 };

Определите свой собственный интерфейс PartialMayBeNull:

type PartialMayBeNull<T> = {
  [P in keyof T]: T[P] | null
}

Использование:

const example: PartialMayBeNull<IExample> = {
  property1: null,
  property2: null,
}

Если вы хотите сделать свойство необязательным и иметь значение null, измените приведенную выше реализацию:

type PartialMayBeNull<T> = {
  [P in keyof T]?: T[P] | null
}

Извините, я упустил из виду, что это повлияет на обязательные свойства, измените их следующим образом.


interface IExample {
  property1: string
  property2: number
  property3?: number
  property4?: string
}

type IsPartialProperty<K extends keyof T, T> = undefined extends T[K] ? K : never
type IsRequiredProperty<K extends keyof T, T> = undefined extends T[K] ? never : K

type PartialProperties<T> = {
  [K in keyof T as IsPartialProperty<K, T>]: T[K] | null
}
type RequiredProperties<T> = {
  [K in keyof T as IsRequiredProperty<K, T>]: T[K]
}
type PartialMayBeNull<T> = PartialProperties<T> & RequiredProperties<T>

const example: PartialMayBeNull<IExample> = {
  property1: 'foo',
  property2: null, // Error: Type null is not assignable to type number
  property3: null, // No error
}

Это также влияет на необязательные свойства.

Deepak Gupta 29.08.2024 08:36

Это сделает все свойства обнуляемыми, а не только необязательные.

VLAZ 29.08.2024 08:36

Ответ был изменен со ссылкой на другой вопрос

二号去听经 29.08.2024 09:15

В {x: string | undefined} свойство x не является необязательным, но этот код будет рассматривать его как таковое.

jcalz 29.08.2024 15:16
  type SetOptionalKeysNullable<T> = {
    [K in keyof T]: T[K] extends NonNullable<T[K]>
      ? T[K]
      : T[K] | null | undefined;
  };

Это то, что сработало для меня

Для чего это нужно {a: string | null, b: number | undefined}? Ни одно из этих свойств не является необязательным, но ваш код добавит undefined к первому и null ко второму.

jcalz 29.08.2024 15:15
Ответ принят как подходящий

Лучший способ обнаружить необязательные свойства — использовать (небезопасную, но удобную) возможность назначения отсутствующего свойства дополнительному свойству отсутствующему свойству. То есть {} можно присвоить {a?: string}, но не {a: string} или {a: string | undefined}. Любая проверка, которая просто смотрит на undefined, в конечном итоге не сможет отличить необязательные свойства от обязательных свойств, ожидающих undefined. Итак, для каждого свойства K в keyof T, если {} присваивается Pick<T, K>, то K необязательно в T:

type SetOptionalKeysNullable<T> = {
  [K in keyof T]: T[K] | ({} extends Pick<T, K> ? null : never)
};

Давайте проверим это:

interface IExample {
  property1: string;
  property2: number;
  property3?: number;
  property4?: string;
}    
type ExOut = SetOptionalKeysNullable<IExample>;
/* type ExOut = {
    property1: string;
    property2: number;
    property3?: number | null | undefined;
    property4?: string | null | undefined;
} */

// none of these properties are optional
type Also = SetOptionalKeysNullable<{
  a: string; 
  b: string | null;
  c: string | undefined;
}>
type AlsoOut = SetOptionalKeysNullable<Also>;
/* type AlsoOut = {
    a: string;
    b: string | null;
    c: string | undefined;
} */

Выглядит хорошо. Все необязательные свойства null добавляются в их домен, тогда как ни с одним из обязательных свойств ничего не происходит.

Детская площадка, ссылка на код

Другие вопросы по теме