Typescript: убедитесь, что у типа есть свойство A, если у него также есть свойство B

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

type MyType = {
  a: string;
  b: string;
  c?: number;
  d?: string;
}

Существуют объекты этого типа, которые могут выглядеть так:

const myObj1: MyType = { a, b };
const myObj2: MyType = { a, b, c, d };

Итак, если объект MyType имеет свойство c, он обязательно будет иметь свойство d. Есть ли способ определить этот тип как таковой, чтобы мне не нужно было ненулевое утверждение или проверку для обоих типов, кроме расширения типа на другой тип?

кроме расширения типа в другой тип? Вы имеете в виду, что не хотите изменять определение MyType?
CertainPerformance 17.05.2022 01:48

Я не хотел иметь что-то вроде: MyType для a и b, и MyType2 для всех a,b,c,d, потому что тогда мне пришлось бы модифицировать другие типы, а также побочные эффекты. Ваш ответ работает для меня, я думаю. Спасибо.

cSharp 17.05.2022 01:56
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой 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
28
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Если вам разрешено изменять MyType, один из подходов состоит в том, чтобы разделить свойства c и d на другой объект, где они необходимы, и чередовать с пересечением с этим объектом.

type AB = {
    a: string;
    b: string;
};
type MyType = AB | AB & {
    c: number;
    d: string;
}

Таким образом, если что-то из MyType имеет свойство c, TypeScript увидит, что оно определенно также имеет свойство d.

Как мне проверить, относится ли объект MyType к типу AB или ко второму типу &? В настоящее время по умолчанию используется AB и выдает ошибку в выражении if. Я проверяю, есть ли у такого объекта c, например if (myObj.c)

cSharp 17.05.2022 02:03

Перед сужением его следует рассматривать только как MyType, что является союзом. Чтобы сузить без ошибок TS, вы можете использовать if ('c' in myObj)

CertainPerformance 17.05.2022 02:09

Верно. if ('c' in myObj) работает отлично. Спасибо.

cSharp 17.05.2022 02:10

Если вы хотите, чтобы свойство «d» существовало только тогда, когда определено «c», и наоборот, было бы целесообразно использовать интерфейсы extended и перезаписать необязательные свойства как never следующим образом:

type Base = {
  a: string;
  b: string;
  c?: number;
  d?: string;
} 

interface Concrete1 extends Base {
  c?: never;
  d?: never;
}
    
interface Concrete2 extends Base {
  c: number;
  d: string;
}

type MyType = Concrete1 | Concrete2;

const myObj1: MyType = { a: 'a', b: 'b' }; ?
const myObj2: MyType = { a: 'a', b: 'b', c: 2 }; ❌
const myObj3: MyType = { a: 'a', b: 'b', c: 2, d: 'd' }; ?

Это гарантирует, что объект MyType всегда будет содержать свойства a, b или a,b,c,d.

Ссылка на детская площадка.

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