简体   繁体   English

在打字稿中使用泛型休息运算符

[英]Rest operator with generics in Typescript

Consider the following code...考虑以下代码...

I would expect the spread operator to be valid code, but it ends up not being so.我希望扩展运算符是有效代码,但最终并非如此。 I'm hoping somebody with expertise in Typescript can advise on why this is...我希望在打字稿方面具有专业知识的人可以就为什么会这样...

export default function convertToGlobalFragment<
  T extends basicFragmentRecipe_T
>(
  fragmentFactory: (recipe: T) => configFragment_I,
  recipe: T & { matchingRules: globalMatchingRules_T }
): globalConfigFragment_I {

  let {
    matchingRules,
    ...restOfRecipe
  }: { matchingRules: globalMatchingRules_T, restOfRecipe: T } = recipe;

}

The error code错误代码

Property 'restOfRecipe' is missing in type 'basicFragmentRecipe_T & { matchingRules: globalMatchingRules_T; }' but required in type '{ matchingRules: globalMatchingRules_T; restOfRecipe: T; }'.ts(2741)

recipe is basicFragmentRecipe_T plus { matchingRules: globalMatchingRules_T } and it seems that basicFragmentRecipe_T does not have restOfRecipe prop at all. recipebasicFragmentRecipe_T加上{ matchingRules: globalMatchingRules_T }似乎basicFragmentRecipe_T根本没有restOfRecipe道具。

You need to indicate the same target type to assign recipe :您需要指定相同的目标类型来分配recipe

let {
    matchingRules,
    ...restOfRecipe
  }: { matchingRules: globalMatchingRules_T } & T = recipe;
let {
    matchingRules,
    ...restOfRecipe
  }: { matchingRules: globalMatchingRules_T, restOfRecipe: T } = recipe;

This part is wrong because recipe doesn't contain a property called restOfRecipe - it's { matchingRules: globalMatchingRules_T } & T - where T is assignable to basicFragmentRecipe_T这部分是错误的,因为 recipe 不包含名为restOfRecipe的属性 - 它是{ matchingRules: globalMatchingRules_T } & T - 其中T可分配给basicFragmentRecipe_T

You can pull out restOfRecipe without this code - let TS do the work:您可以在没有此代码的情况下提取 restOfRecipe - 让 TS 来完成这项工作:

  let { matchingRules, ...restOfRecipe } = recipe;

Now restOfRecipe is of type:现在 restOfRecipe 是类型:

在此处输入图片说明

Pick<T & { matchingRules: globalMatchingRules_T; }, Exclude<keyof T, "matchingRules">>

Let's break that down.让我们分解一下。

The type of recipe is the combination of T and { matchingRules: globalMatchingRules_T; }配方的类型是T{ matchingRules: globalMatchingRules_T; }的组合{ matchingRules: globalMatchingRules_T; } { matchingRules: globalMatchingRules_T; }

To get from this type the properties except 'matchingRules' - we need to exclude matchingRules from T and { matchingRules: globalMatchingRules_T; }要从这种类型中获取除 'matchingRules' 之外的属性 - 我们需要从T{ matchingRules: globalMatchingRules_T; }排除匹配{ matchingRules: globalMatchingRules_T; } { matchingRules: globalMatchingRules_T; } . { matchingRules: globalMatchingRules_T; } . As the latter part will always contain matchingRules, we can skip checking the combination and just look at Exclude<keyof T, "matchingRules" to get the keys of T without 'matchingRules'.由于后半部分将始终包含匹配规则,我们可以跳过检查组合,只需查看Exclude<keyof T, "matchingRules"即可获取 T 的键,而无需 'matchingRules'。

Finally we then use Pick<T, K> to pick the keys of T (without matchingRules ) from the type of Recipe , giving us the result above.最后,我们使用Pick<T, K>接的键T (没有matchingRules从的类型) Recipe ,给我们上面的结果。

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

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