考虑下面的代码,该代码尝试有条件地向具有推断类型的对象添加属性:
const foo = {
a: 1,
b: 2,
};
if (bar) {
foo.c = 3; // Error: Property 'c' does not exist on type '{ a: number; b: number; }'.(2339)
}可以通过显式地将foo类型声明为{ a: number; b: number; c?: number; }或使用展开来有条件地添加c来消除错误
const foo = {
a: 1,
b: 2,
...(bar ? { c: 3 } : {}),
};但是,假设我们想要保留原始代码结构,但又想避免必须显式声明可以推断的属性。有没有什么解决方案可以同时满足这两个要求?例如,是否有可能以某种方式调整推断的类型,例如:
const foo = {
a: 1,
b: 2,
} as { ...; c?: number; }; // Example, does not work发布于 2020-12-14 14:38:00
这并不美观,但它是有效的:a和b的属性类型是推断出来的,并且不需要重复声明。
function withMissingProps<T>() {
return function<S>(obj: S): S & Partial<T> {
return obj;
}
}
const foo = withMissingProps<{ c: number }>()({
a: 1,
b: 2
});
if(Math.random() > 0.5) {
foo.c = 1;
}声明属性和推断属性分别有两个类型参数T和S。不幸的是,如果一个函数有两个类型参数,那么你必须同时提供两个类型参数,或者同时推断两个类型参数;解决方案是使用curry函数,尽管这意味着额外的一对括号。
发布于 2020-12-16 21:53:31
我还发现了这个漏洞,不幸的是,它编译成了Object.assign,因此具有非零的运行时成本:
const foo = {
a: 1,
b: 2,
...{} as {
c?: number,
},
};https://stackoverflow.com/questions/65284452
复制相似问题