javascript - 为什么在这个可选链中我会收到“对象可能是‘undefined’”?
我到了这里:
buyTicketData?.pricingOptions
这个错误:
[tsl] ERROR in /Applications/MAMP/htdocs/wp-content/plugins/tikex/tikexModule/components/BuyTicket/PricingOptionInvoiceItemsFormFieldsCheckboxes.tsx(280,25)
TS2532: Object is possibly 'undefined'.
如果 ? 的左侧是未定义的,为什么会重要,? 不是会包裹它吗?
类型如下:
buyTicketData?: BuyTicketData;
export type BuyTicketData = {
pricingOptions?: PricingOptions;
}
export type PricingOptions = {
[optionId: string]: PricingOptionType;
};
export type PricingOptionType = {
invoiceItems?: InvoiceItems;
};
export type InvoiceItems = {
[invoiceItemId: string]: InvoiceItemData;
};
export type InvoiceItemData = {
defaultValue?: number;
};
无论如何,这就是整个表达
<select
value={
startPaymentIn?.invoiceItems?.[key] != undefined
? startPaymentIn?.invoiceItems?.[key] == 1
? "Igen"
: "Nem"
: startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[ // <-- here
startPaymentIn!.pricingOptionId!
].invoiceItems[key]?.defaultValue != undefined
? startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[
startPaymentIn!.pricingOptionId!
].invoiceItems[key]?.defaultValue == 1
? "Igen"
: "Nem"
: undefined
}
好的,找到解决方案:
value={
startPaymentIn?.invoiceItems?.[key] != undefined
? startPaymentIn?.invoiceItems?.[key] == 1
? "Igen"
: "Nem"
: buyTicketData?.pricingOptions?.[
startPaymentIn?.pricingOptionId ?? ""
]?.invoiceItems?.[key]?.defaultValue != undefined
? buyTicketData?.pricingOptions?.[
startPaymentIn?.pricingOptionId ?? ""
]?.invoiceItems?.[key]?.defaultValue == 1
? "Igen"
: "Nem"
: undefined
}
我只是不明白为什么需要这个丑陋的 ?? "" 条件。
答案#1
如果 a 是 undefined,a.b 会抛出异常,而 a?.b 会解析为 undefined。你仍然需要处理 undefined。
buyTicketData?.pricingOptions?.[startPaymentIn?.pricingOptionId]
解析为
buyTicketData?.pricingOptions?.[undefined]
如果 startPaymentIn 是 undefined。这将抛出错误,因为 undefined 不能作为键。
如果这个变量是必需的,更好的方法是在所有操作之前进行空检查,这样你就完全不需要 ?. 了。
if(startPaymentIn)
{
//no need to use ?. on startPayment
}
答案#2
你漏掉了一个可能未定义的 invoiceItems 的可选链操作符。defaultValue 的查找应该像这样:
buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!]
.invoiceItems?.[key]?.defaultValue
以下最小可复现示例说明了这一点。可以在 Playground 中尝试它以查看错误。
export type BuyTicketData = {
pricingOptions?: PricingOptions;
}
export type PricingOptions = {
[optionId: string]: PricingOptionType;
};
export type PricingOptionType = {
invoiceItems?: InvoiceItems
}
export type InvoiceItems = {
[invoiceItemId: string]: InvoiceItemData
}
export type InvoiceItemData = {
defaultValue?: number
}
let startPaymentIn: PricingOptionType & { pricingOptionId?: string } = {}
function testContext (key: string, buyTicketData?: BuyTicketData) {
// incrementally testing your expression until we isolate the actual error
let w = buyTicketData?.pricingOptions
let x = buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!]
let y = buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!].invoiceItems
let z = buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!].invoiceItems[key]
// ^^^ error on this last line
// the correct expression to get the `defaultValue`
const defaultValue =
buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!].invoiceItems?.[key]?.defaultValue
return startPaymentIn?.invoiceItems?.[key] != undefined
? startPaymentIn?.invoiceItems?.[key] == 1
? "Igen"
: "Nem"
: startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[
startPaymentIn!.pricingOptionId!
].invoiceItems?.[key]?.defaultValue != undefined
? startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[
startPaymentIn!.pricingOptionId!
].invoiceItems?.[key]?.defaultValue == 1
? "Igen"
: "Nem"
: undefined
}
