英文:
Property 'x' does not exist on type (when checking if it exists)
问题
我当前代码的相关部分如下所示:
(代码编辑自 https://github.com/expo/expo-server-sdk-node)
const tickets: ExpoPushTicket[] = [], receiptIds = [];
...
for (const ticket of tickets) {
if (ticket.id) {
receiptIds.push(ticket.id);
}
}
类型定义如下(来自 expo-server-sdk 库):
export declare type ExpoPushSuccessTicket = {
status: 'ok';
id: ExpoPushReceiptId;
};
export declare type ExpoPushErrorTicket = ExpoPushErrorReceipt;
export declare type ExpoPushErrorReceipt = {
status: 'error';
message: string;
details?: {
error?: 'DeviceNotRegistered' | 'InvalidCredentials' | 'MessageTooBig' | 'MessageRateExceeded';
};
__debug?: any;
};
export declare type ExpoPushTicket = ExpoPushSuccessTicket | ExpoPushErrorTicket;
问题是 if (ticket.id)
报错 Property 'id' does not exist on type 'ExpoPushTicket'
。
if 语句的目的是检查属性 id 是否存在,因为只有在出现错误时它才是未定义的。
我尝试使用 Object.prototype.hasOwnProperty
方法来避免在 if
行上出现编译错误,但在 receiptIds.push(ticket.id)
上仍然存在错误。
请问,如何正确地检查我的 ticket
是否包含该属性?
我应该导入并更改 ExpoPushTicket 的类型吗?
英文:
The relevant part of my current code looks like this:
(code edited from https://github.com/expo/expo-server-sdk-node)
const tickets: ExpoPushTicket[] = [], receiptIds = [];
...
for (const ticket of tickets) {
if (ticket.id) {
receiptIds.push(ticket.id);
}
}
where the types look like this (from expo-server-sdk library):
export declare type ExpoPushSuccessTicket = {
status: 'ok';
id: ExpoPushReceiptId;
};
export declare type ExpoPushErrorTicket = ExpoPushErrorReceipt;
export declare type ExpoPushErrorReceipt = {
status: 'error';
message: string;
details?: {
error?: 'DeviceNotRegistered' | 'InvalidCredentials' | 'MessageTooBig' | 'MessageRateExceeded';
};
__debug?: any;
};
export declare type ExpoPushTicket = ExpoPushSuccessTicket | ExpoPushErrorTicket;
The issue is if (ticket.id)
gives Property 'id' does not exist on type 'ExpoPushTicket'
.
The purpose of the if in itself was to see if the property id existed, since it's undefined only if there is an error.
I checked to see if there were other methods and found Object.prototype.hasOwnProperty
which managed to not give a compilation error on the if
line, but the error was still there on receiptIds.push(ticket.id)
.
What is the correct way to check if my ticket
contains the property?
Should I import and change the type of ExpoPushTicket?
答案1
得分: 1
类型ExpoPushTicket
是一个联合类型。如果没有类型保护,只有在所有联合成员上存在该属性时才能访问它。在你的情况下,首先使用类型保护检查特定类型,然后访问id
字段。
最简单的解决方案可能是使用in
运算符:
for (const ticket of tickets) {
if ("id" in ticket) {
receiptIds.push(ticket.id);
}
}
这个检查将联合类型缩小到ExpoPushSuccessTicket
,在这个类型上访问id
字段是合法的。
英文:
The type ExpoPushTicket
is a union type. Without a type guard you can only access a property if it exists on all union participants. In your case check first for a specific type using a type guard and then access the id
field.
The simplest solution is probably the in
operator:
for (const ticket of tickets) {
if ("id" in ticket) {
receiptIds.push(ticket.id);
}
}
This check narrows the union type to ExpoPushSuccessTicket
where accessing the id
field is legal.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论