У меня есть тип, который выглядит примерно так:
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
для a
и b
, и MyType2
для всех a,b,c,d
, потому что тогда мне пришлось бы модифицировать другие типы, а также побочные эффекты. Ваш ответ работает для меня, я думаю. Спасибо.
Отвечает ли это на ваш вопрос? Typescript - свойства a и b как существовать или не существовать одновременно
Если вам разрешено изменять 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)
Перед сужением его следует рассматривать только как MyType
, что является союзом. Чтобы сузить без ошибок TS, вы можете использовать if ('c' in myObj)
Верно. if ('c' in myObj)
работает отлично. Спасибо.
Если вы хотите, чтобы свойство «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
.
Ссылка на детская площадка.
MyType
?