我怎样才能对同一个对象进行类型保护?
How can I do type-guarding for the same object?
比如我有这样一段代码:
interface Subscriber {
reviewData: string | string[]
hasArray: boolean;
}
const reviews = ["Good", "Not bad"];
const subscriber: Subscriber = {
reviewData: reviews,
hasArray: Array.isArray(reviews)
}
if (subscriber.hasArray) {
subscriber.reviewData.forEach(console.log);
} else {
console.log(subscriber.reviewData);
}
当然,TypeScript 会在 subscriber.reviewData.forEach(console.log);
处抱怨说它无法定义它是一个数组还是一个字符串,因为条件 subscriber.hasArray
.[=16 中没有足够的类型保护=]
我不想总是写 Array.isArray(subscriber.reviewData)
因为我会在很多其他地方使用这个逻辑。
我听说过 is
,但在我的场景中情况并非如此,因为使用 is
意味着您必须有一个函数并将一些参数传递给它。
怎样才能达到预期的效果?
如果您希望能够使用 hasArray
来确定 reviewData
是 string[]
还是 string
,那么您确实需要 Subscriber
成为 discriminated union type 而不是接口。您的界面将允许 {reviewData: "", hasArray: true}
,因此编译器无法排除这种可能性。使用可区分的联合,您可以检查一个 可区分的 属性 以缩小整个对象的类型:
type Subscriber = {
reviewData: string[]
hasArray: true;
} | {
reviewData: string
hasArray: false;
}
在这种情况下 hasArray
是布尔值 literal type true
或 false
.
的判别式 属性
然后,给定一个 Subscriber
:
const subscriber: Subscriber = Math.random() < 0.5 ?
{ reviewData: "Good", hasArray: false } :
{ reviewData: ["Who", "Cares"], hasArray: true };
我们可以按照您想要的方式进行检查,不会出现编译错误:
if (subscriber.hasArray) {
subscriber.reviewData.forEach(console.log);
} else {
console.log(subscriber.reviewData.toUpperCase());
}
比如我有这样一段代码:
interface Subscriber {
reviewData: string | string[]
hasArray: boolean;
}
const reviews = ["Good", "Not bad"];
const subscriber: Subscriber = {
reviewData: reviews,
hasArray: Array.isArray(reviews)
}
if (subscriber.hasArray) {
subscriber.reviewData.forEach(console.log);
} else {
console.log(subscriber.reviewData);
}
当然,TypeScript 会在 subscriber.reviewData.forEach(console.log);
处抱怨说它无法定义它是一个数组还是一个字符串,因为条件 subscriber.hasArray
.[=16 中没有足够的类型保护=]
我不想总是写 Array.isArray(subscriber.reviewData)
因为我会在很多其他地方使用这个逻辑。
我听说过 is
,但在我的场景中情况并非如此,因为使用 is
意味着您必须有一个函数并将一些参数传递给它。
怎样才能达到预期的效果?
如果您希望能够使用 hasArray
来确定 reviewData
是 string[]
还是 string
,那么您确实需要 Subscriber
成为 discriminated union type 而不是接口。您的界面将允许 {reviewData: "", hasArray: true}
,因此编译器无法排除这种可能性。使用可区分的联合,您可以检查一个 可区分的 属性 以缩小整个对象的类型:
type Subscriber = {
reviewData: string[]
hasArray: true;
} | {
reviewData: string
hasArray: false;
}
在这种情况下 hasArray
是布尔值 literal type true
或 false
.
然后,给定一个 Subscriber
:
const subscriber: Subscriber = Math.random() < 0.5 ?
{ reviewData: "Good", hasArray: false } :
{ reviewData: ["Who", "Cares"], hasArray: true };
我们可以按照您想要的方式进行检查,不会出现编译错误:
if (subscriber.hasArray) {
subscriber.reviewData.forEach(console.log);
} else {
console.log(subscriber.reviewData.toUpperCase());
}