简体   繁体   English

如何使用 TypeScript 定义文件将新类型 Map 转换为元组类型的元素?

[英]How Can I Map a New Type to an Element of a Tuple Type using a TypeScript Definition File?

I have a function signature imported from a third party library.我有一个从第三方库导入的 function 签名。 I have a declaration file ( node-api.d.ts ) that I'd like to add a new type into which changes the type of one of the parameters to the function based off the imported function so that I catch any changes by the third-party lib author to their signature, like so:我有一个声明文件( node-api.d.ts ),我想添加一个新类型,根据导入的 function 将其中一个参数的类型更改为 function 以便我捕捉到任何更改第三方库作者为其签名,如下所示:

type ImportedMethod = (
  this: void,
  extension: object,
  otherParams: any
) => void

type ChangedMethod = (
  this: void,
  extension: MyExtensionType,
  otherParams: any
) => void

I think the way to do this is to use the Parameters utility function and get a tuple type (is that the correct term?) of the parameters, modify the type of the element I'm interested in, and then spread that new tuple type in a new function signature:我认为这样做的方法是使用Parameters实用程序 function 并获取参数的元组类型(这是正确的术语吗?),修改我感兴趣的元素的类型,然后传播新的元组类型在新的 function 签名中:

// [extension: object, otherParams: any]
type Params = Parameters<ImportedMethod>

// @TODO: Figure out how to transform the `extension`
// element's type of my "tuple type" to a new type

type ChangedMethod = (
  ...args: ModifiedParams
) => void

I can't figure out how to change the type of an element of the tuple type .我不知道如何更改元组类型元素的类型 I think I need to use mapped and conditional types, but I'm not sure how to introduce the string literal as a condition:我想我需要使用映射类型和条件类型,但我不确定如何将字符串文字作为条件引入:

type SwapExtensionElement<T> = {
  [K in keyof T]: K extends 'extension' ? MyExtensionType : T[K]
}

type ModifiedParams = SwapExtensionElement<ImportedMethod>
// [extension: object, otherParams: any]

I'd sure appreciate any help.我肯定会感谢任何帮助。

If you know the position, you can infer parts of the parameters tuple, and the reassemble new parameters.如果您知道 position, 您可以infer部分参数元组,并重新组装新参数。

In this case you need everything but the first paramter, since that one is getting replaced.在这种情况下,您需要除第一个参数之外的所有参数,因为该参数已被替换。 So let's use a utility type called Tail :因此,让我们使用一个名为Tail的实用程序类型:

type Tail<T extends unknown[]> =
    T extends [infer _, ...infer Rest] ? Rest : never

type Test = Tail<[1, 2, 3]> // [2, 3]

This takes a tuple and pulls out the first element to an ignored type _ , and everything after into Rest and then resolves to Rest .这需要一个元组并将第一个元素拉出到忽略的类型_ ,然后将所有内容拉入Rest ,然后解析为Rest

You can then create your method type like this:然后,您可以像这样创建您的方法类型:

type ChangedMethod = (
  this: void,
  extension: MyExtensionType,
  ...args: Tail<Params>
) => void

The IDE then reports the type of ChangedMethod as: IDE 然后将ChangedMethod的类型报告为:

type ChangedMethod = (this: void, extension: MyExtensionType, otherParams: any) => void

Playground 操场

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

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