如何从打字稿中的类型中排除仅吸气剂的属性 [英] How to exclude getter only properties from type in typescript
问题描述
类中的字母是只读属性,因此以下代码引发类型错误是有意义的.
Getters in the class are readonly properties so throwing type error from following code make sense.
class Car {
engine: number;
get hp() {
return this.engine / 2;
}
get kw() {
return this.engine * 2;
}
}
function applySnapshot(
car: Car,
snapshoot: Partial<Car> // <-- how to exclude readonly properties?
) {
for (const key in snapshoot) {
if (!snapshoot.hasOwnProperty(key)) continue;
car[key as keyof Car] = snapshoot[key as keyof Car];
// Cannot assign to 'hp' because it is a constant or a read-only property.
}
}
有没有一种方法可以强制转换仅可写属性以键入和排除所有吸气剂?
Is there a way how to cast writable only properties to type and exclude all getters?
推荐答案
编辑
有关此问题的解决方法,请参见@ matt-mccutchen. Edit
See @matt-mccutchen for an intresting workaround to this issue. 原始答案 这是一个已知问题,在此处中记录. This is a known issue, documented here. 由于此可分配性规则,无法在条件类型中区分只读字段和可变字段之间的差异. Because of this assignability rule there is no way to distinguish in conditional types the difference between a readonly field and a mutable one. 一种解决方法是在只读字段类型中添加一些额外的内容.这不会影响您如何使用该字段,但会为我们提供一个删除密钥的钩子. One workaround is to add something extra to the type of readonly fields. This will not impact how you can use the field but it will give us a hook to remove the key. 这篇关于如何从打字稿中的类型中排除仅吸气剂的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!readonly
是一个相当弱的修饰符,因为它不会影响可分配性.因此,例如,您可以将具有readonly
属性的对象分配给具有相同可变属性的对象,并且编译器不会抱怨:readonly
is a rather weak modifier in that is does not impact assignability. So for example you can assign an object with readonly
properties to one with those same mutable properties and the compiler will not complain:let roCar: Partial<Car> = { hp: 10 } // we can assign a mutable object to a referecne with a readonly property
roCar.hp = 10; // error hp is readonly
//But we can also assign an object with a readonly property to a fully mutable version of it
let allMutableCar: { -readonly [P in keyof Car]: Car[P] } = new Car();
allMutableCar.hp = 10; // No compile time error
type readonly = { readonly?: undefined };
class Car {
engine!: number;
get hp() : number & readonly {
return this.engine / 2;
}
get kw() : number & readonly {
return this.engine * 2;
}
}
type NoReadonlyKeys<T> = { [P in keyof T]: 'readonly' extends keyof T[P] ? never : P }[keyof T]
type PartialNoReadonly<T> = Partial<Pick<T, NoReadonlyKeys<T>>>
type Mutable<T> = { -readonly [P in keyof T]: T[P] }
function applySnapshot(
car: Car,
snapshoot: PartialNoReadonly<Car>
) {
const mutableCar: Mutable<Car> = car; // erase readonly so we can mutate
for (const key in snapshoot) {
let typedKey = key as keyof typeof snapshoot
if (!snapshoot.hasOwnProperty(key)) continue;
mutableCar[typedKey] = snapshoot[typedKey] as any;
}
}
applySnapshot(new Car(), {
engine: 0
})
applySnapshot(new Car(), {
hp: 0 /// error
})