简体   繁体   English

Typescript object 解构中的条件类型

[英]Typescript conditional types in object destructuring

I want to call a function with an object as only argument.我想用 object 作为唯一参数来调用 function。 This object can be two different interfaces which collides (1+ properties have the same key but different possible values).这个 object 可以是两个不同的接口发生冲突(1+ 属性具有相同的键,但可能的值不同)。

In my main function, I want to call getFoo if the type value in the object if foo and getBar if the type value in the object if bar .在我的主要 function 中,如果 object 中的类型值如果foogetBar如果 object 如果bar中的类型值,我想调用getFoo

interface Foo {
  title: string
  number: 1 | 2
}
interface FooWithType extends Foo {
  type: 'foo'
}

interface Bar {
  title: string
  number: 3 | 4
}
interface BarWithType extends Bar {
  type: 'bar'
}

function getFoo(params: Foo): void
function getBar(params: Bar): void

function main({ type, ...rest }: FooWithType | BarWithType) {
  return type === 'foo' ? getFoo(rest) : getBar(rest)
}

I have a TypeScript issue when I'm doing a conditional type on a destructured object where Type '{ title: string; number: 3 | 4; }' is not assignable to type 'Foo'当我在解构的 object where Type '{ title: string; number: 3 | 4; }' is not assignable to type 'Foo' Type '{ title: string; number: 3 | 4; }' is not assignable to type 'Foo' Type '{ title: string; number: 3 | 4; }' is not assignable to type 'Foo' because my rest value is still an union type when I typecheck it: Type '{ title: string; number: 3 | 4; }' is not assignable to type 'Foo'因为我的rest值在我进行类型检查时仍然是联合类型:

var rest: {
    title: string;
    number: 1 | 2;
} | {
    title: string;
    number: 3 | 4;
}

Typescript do not understand the rest type because it's destructured so uncorrelated to the type value. Typescript 不理解 rest 类型,因为它已解构,因此与类型值无关。 There's two possible ways to fix it without edit anything but the main function .除了主要的 function 之外,有两种可能的方法可以在不编辑任何内容的情况下修复它。

The first is type assertion ( not recommended ):首先是类型断言(不推荐):

function main({ type, ...rest }: FooWithType | BarWithType) {
  return type === 'foo' ? getFoo(rest as Foo) : getBar(rest as Bar)
}

playground link 游乐场链接


The second is to not destructure your object ( better way ):第二个是不要破坏你的 object (更好的方法):

function main(params: FooWithType | BarWithType) {
  return params.type === 'foo' ? getFoo(params) : getBar(params)
}

playground link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM