gpt4 book ai didi

typescript - 使用 TypeScript 将箭头函数分配给通用函数类型

转载 作者:行者123 更新时间:2023-12-04 16:05:06 26 4
gpt4 key购买 nike

我已经对类似问题进行了一些挖掘,但我找不到有效的解决方案。我有一些类型的通用函数,但我似乎无法正确实现它们。

简而言之,我有这个:

/** Takes three values of the same type and collapses them into one */
declare type MergeFunction = <T>(def: T, file?: T, arg?: T) => T

/** The implementation I'm having trouble with. Merge three arrays of the same type. */
const arrayMerge: MergeFunction = <T>(def: T[], file: T[] = [], arg: T[] = []): T[] => [ ].concat(def).concat(file || [ ]).concat(arg || [ ])

但是,我得到一个编译器错误:

Property 'arrayMerge' is incompatible with index signature.
Type '<A>(def: A[], file?: A[], arg?: A[]) => A[]' is not assignable to type 'MergeFunction'.
Types of parameters 'def' and 'def' are incompatible.
Type 'T' is not assignable to type '{}[]'.

我如何实际实现这种类型?

最佳答案

正如您所定义的,MergeFunction 类型的函数必须适用于任何类型T 调用者指定的。所以arrayMerge 不是 MergeFunction ,因为它只接受数组。这是实现您的 MergeFunction 的一种方法如指定:

declare type MergeFunction = <T>(def: T, file?: T, arg?: T) => T;
const returnLastSpecifiedThing: MergeFunction = <T>(def: T, file?: T, arg?: T) =>
typeof arg !== 'undefined' ? arg :
typeof file !== 'undefined' ? file :
def;

事实上,在实现像 MergeFunction 这样的类型时,您唯一可以安全地做的事。是返回输入之一,因为 you don't know anything about T 因为调用者负责。肯定无法确定 T是一个数组。


也许你的意思是 MergeFunction成为 实现者 选择泛型参数 T 的类型.在这种情况下,您可以使 type 通用而不是 function:

declare type MergeFunction<T> = (def: T, file?: T, arg?: T) => T;

注意 <T>从函数移到类型。原来的定义是一个特定类型别名,它指的是一个泛型函数类型,而新定义是一个泛型类型别名,当你为 T 插入一个值, 指的是一个特定的函数类型。 (抱歉,如果这令人困惑。)现在实现 some 特定类型的 this 要容易得多。例如:

const concatenateStrings: MergeFunction<string> = 
(def: string, file?: string, arg?: string) =>
def + (file ? file : "") + (arg ? arg: "");

函数concatenateStringsMergeFunction<string> .

在这一点上,表示arrayMerge 似乎应该很简单。作为某种MergeFunction<> .不幸的是,事实并非如此。 TypeScript 缺少 the sort of generics你需要在这里。你想要说的是这样的:

const arrayMerge: <T> MergeFunction<T[]> = // invalid syntax
(def: T[], file: T[] = [], arg: T[] = []): T[] =>
([] as T[]).concat(def).concat(file || []).concat(arg || []);

但是您不能直接这样做(如链接问题所述)。最接近的就是加一层间接性,比如函数调用:

const makeArrayMerge = <T>(): MergeFunction<T[]> =>
(def: T[], file: T[] = [], arg: T[] = []): T[] =>
([] as T[]).concat(def).concat(file || []).concat(arg || []);

现在 makeArrayMerge是一个函数,当使用指定的类型参数 T 调用时, 产生一个 MergeFunction<T> .这可行,但更难使用(并且不会以您想要的方式推断类型):

const numArray = makeArrayMerge<number>()([0, 1, 2], [3, 4, 5]);

好吧,鉴于 TypeScript 泛型的限制,这是我能做的最好的事情。由您决定是否真的需要上述间接方式,或者某些特定的数组类型是否适合您。希望有帮助。祝你好运!

关于typescript - 使用 TypeScript 将箭头函数分配给通用函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50933740/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com