如何避免 enumerable: false 属性的编译器错误

2024-04-27

我正在尝试学习 TS,但我遇到了一个奇怪的案例场景。

我有一个对象,其属性设置为不可枚举:

let person = {
  name: 'Harry'
}

Object.defineProperty(person,'salary',{enumerable: false, value : 15});

console.log(person.salary); // 15

这在运行时有效,但是编译器会出错:

类型“{ name: string;”上不存在属性“salary” }'

这是预期的。

我可以绕过此设置,将人员类型设置为任何类型,但感觉不是一个干净的解决方案。

还有其他方法吗?非空断言运算符对此不起作用。

如果有人能分享一些这方面的知识,我将不胜感激。


虽然您可以更改类型注释person,也许像:

let person: { name: string; salary?: number } = {
  name: 'Harry'
};

or even:

let person = {
  name: 'Harry'
} as { name: string; salary: number };

最安全的方法可能是(ab)使用断言函数 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions在 3.7 版本中:

function defineProperty<
    O,
    Property extends PropertyKey,
    Value
>(o: O, key: Property, attributes: PropertyDescriptor & ThisType<any> & { value: Value }): asserts o is O & Record<Property, Value> {
    Object.defineProperty(o, key, attributes);
}

它本质上是一个包装函数Object.defineProperty告诉 TypeScript,如果这个函数没有抛出错误,那么给定值的类型o is O & Record<Property, Value>.

所以当你使用它时,你会得到这样的类型:

defineProperty(person,'salary',{enumerable: false, value : 15});

person
// ^? { name: string; } & Record<"salary", number>

操场 https://tsplay.dev/mx3vbN


如果你really如果愿意,您还可以通过将断言更改为以下内容来使结果类型更清晰:

asserts o is (O & Record<Property, Value> extends infer T extends O ? { [K in keyof T]: T[K] } : O)

如你看到的here https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABAEwKbBmVAFATnAB1VygE8AeAWAChE7EB5AGhvsT0OLMVQA8pUYZAGd2+IiVIBpVKRa16ANQCGAGxCoaAPgAUcAFyMmiANazDHCWWPKoUXDABGIAcIviupACKphEBwRQcLiIAGSIACoAFjDCEaRE5MpgpFphiADeiABuahqGKuqoiAC+AJSGysLCXKJwiLGIOgzpAEqoEMHI5JaexoUaaXwCQqKYwMSRPPyCIoyIAPyZiADaUg1IZqRwwJEAuoYRa3uliIYMZZms9AyOAFYdUAB0aBhYvZJ6xls2dg7OrjKAG4aCUaDRVKgoIgJMIEIgALxXBRgZQAW1QhgA5AAJZS4XCkLGgkHUGi3B7QF7oTA4DyfWEIJhY4RqfFEpgZQQgDG4ZSOSGGYBqGrGXJFM6IACMAFZyqSaJ0wHDIU9VHAAOY6RlgJ6s1Ts4Hg6ivWkfMja4hwsDM-XsrGc7m8-mCxDC1SinJ5YqGWXy41KlWoNWay24a16tmEso0IA当悬停在person,现在的类型是{ name: string; salary: number; }而不是一个丑陋的十字路口。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何避免 enumerable: false 属性的编译器错误 的相关文章

随机推荐