[英]Destructured arguments under optional function arguments in typescript throw error
interface Type1 {
attr1: string;
attr2: string;
}
interface Type2 {
attr1: string;
attr2: string;
attr3: string; // extra attribute
}
function fn(config: Type1 | Type2): void {
// Property 'attr3' does not exist on type 'Type1 | Type2'.ts(2339)
const { attr1, attr2, attr3 } = config;
console.log(attr1);
console.log(attr2);
console.log(attr3);
}
错误代码显示之前。 而且我知道有一个解决方案可以在attr3
添加可选属性。 但就我而言,这个解决方案并不好。 因为事实上只有Type1
或Type2
两种情况。 总之,可选方式不是可读性。 如何以高级方式修复它?
您可以简单地检查attr3
是否存在于 object
function fn(config: Type1 | Type2): void {
if ('attr3' in config) {
const {
attr1,
attr2,
attr3
} = config;
} else {
const {
attr1,
attr2
} = config;
}
}
或者您可以使用自定义类型保护
function IsType2(config: Type1 | Type2): config is Type2 {
return (config as Type2).attr3 !== undefined;
}
function fn(config: Type1 | Type2): void {
if (IsType2(config)) {
const {
attr1,
attr2,
attr3
} = config;
} else {
const {
attr1,
attr2
} = config;
}
}
或者如果我们真的只想解构一次,我们可以创建一个连接类型,尽管我们会强制类型而不是推断它。
function fn(config: Type1 | Type2): void {
const {
attr1,
attr2,
attr3
} = config as Type1 & Type2;
}
据我所知,没有办法直接解构联合类型
如果您想在缺少attr3
属性时获得与js
代码相同的结果,您可以将配置类型转换为类型的交集:
interface Type1 {
attr1: string;
attr2: string;
}
interface Type2 {
attr1: string;
attr2: string;
attr3: string; // extra attribute
}
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
function fn(config: Type1 | Type2): void {
// Property 'attr3' does not exist on type 'Type1 | Type2'.ts(2339)
const { attr1, attr2, attr3 } = config as UnionToIntersection<Parameters<typeof fn>[0]>;
console.log(attr1);
console.log(attr2);
console.log(attr3);
}
fn({ attr1: '', attr2: '' })
或者只是... = config as Type1 & Type2;
如果你不介意一些不灵活。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.