我有两种类型,一种包含名为 amount 的属性,另一种不包含。 我想从一个或另一个中解构该属性,以提供一个默认值,以防它不存在(不包含它的类型)。 这是有效的 JS 代码,但是 typescript 抱怨其中一种类型中不存在此类属性,这是正确的,但这就是默认值的用途。
代码如下:
interface A {
amount: number;
name: string;
}
type notA = {
name: string
}
const values = new Map<string, A>()
values.set('test', {name: 'test', amount: 0})
const defaultValue = {name: 'no-test'}
const { amount = 0 } = values.get('tust') || defaultValue
console.log(name, amount)
我知道打字稿试图保护我免受此类属性存在的类型不正确,但从一开始就不应该这样做。 这可能是因为 typescript 没有确切的类型,它允许将额外的 props 附加到没有定义它们的类型,所以我怎样才能使上面的编译?
答案 0 :(得分:0)
答案 1 :(得分:0)
我非常倾向于重构为以下内容:
const { amount } = values.get('tust') || { name: "no-test", amount: 0 };
因为您的意图大概是应该有一个 A
类型的默认值,特别是如果您打算使用 0
作为 amount
属性的默认值。>
但是,假设你不能改变它,我建议给 defaultValue
一个显式注释的类型。当你让编译器推断它的类型时,它变成了 {name: string}
。就其本身而言,这种类型是正确的,但它根本不暗示 amount
属性的任何内容(如您所见,TypeScript 中的对象类型并不准确)。如果您希望编译器了解 defaultValue
可能缺少 amount
属性,则需要将其注释为此类类型。例如:
interface MaybeA {
amount?: number;
name: string;
}
const defaultValue: MaybeA = { name: 'no-test' }
我已经声明了一个 MaybeA
接口,它是 A
的更广泛版本,其中 amount
属性是 optional,所以它的类型是 number
或undefined
。然后,这将按需要工作:
const { amount = 0 } = values.get('tust') || defaultValue // no error
您也可以改写 NotA
类型,它肯定缺少 amount
属性:
interface NotA {
amount?: undefined;
name: string;
}
const defaultValue: NotA = { name: 'no-test' }
const { amount = 0 } = values.get('tust') || defaultValue // also okay
当然,没有什么要求您实际为这些类型命名,特别是如果您只使用它们一次:
const defaultValue: { name: string, amount?: undefined } = { name: 'no-test' }
const { amount = 0 } = values.get('tust') || defaultValue // okay