typescript - 使用 TypeScript 将箭头函数分配给通用函数类型
问题描述
我已经对类似的问题进行了一些挖掘,但我找不到有效的解决方案。我有一些类型的通用函数,但我似乎无法正确实现它们。
简而言之,我有这个:
/** 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
必须适用于调用者指定的任何类型。所以不是a ,因为它只接受数组。这是按照指定实现您的一种方法: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
就是返回其中一个输入,因为您对此一无所知,T
因为调用者负责该操作。当然没有办法确定这T
是一个数组。
也许您的意思是MergeFunction
成为实现者选择泛型参数的类型T
。在这种情况下,您可以将类型设为泛型而不是函数:
declare type MergeFunction<T> = (def: T, file?: T, arg?: T) => T;
请注意如何<T>
从函数移动到类型。原始定义是一个特定的类型别名,它指的是一个泛型函数类型,而新定义是一个泛型类型别名,当你插入一个值时T
,它指的是一个特定的函数类型。(对不起,如果这令人困惑。)现在实现某些特定类型的 this 要容易得多。例如:
const concatenateStrings: MergeFunction<string> =
(def: string, file?: string, arg?: string) =>
def + (file ? file : "") + (arg ? arg: "");
函数concatenateStrings
是一个MergeFunction<string>
。
在这一点上,似乎应该很简单地表示arrayMerge
为某种MergeFunction<>
. 不幸的是,事实并非如此。TypeScript 缺少你需要的那种泛型。你想说的是这样的:
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 || []);
NowmakeArrayMerge
是一个函数,当使用指定的类型参数调用时T
,它会生成一个MergeFunction<T>
. 这有效,但更难使用(并且不会以您想要的方式推断类型):
const numArray = makeArrayMerge<number>()([0, 1, 2], [3, 4, 5]);
哦,好吧,鉴于 TypeScript 泛型的限制,这是我能做的最好的事情。由您决定是否真的需要上述间接方式,或者某些特定的数组类型是否适合您。希望有帮助。祝你好运!
推荐阅读
- reactjs - 一个
可能只有一个子元素。尝试了一切 - mysql - 从 MySQL 中提取所有 JSON 密钥
- swift - 从 CIImage 创建 UIImage 似乎总是失败
- android - Worker 下的多个 OneTimeWorkRequest 导致我的应用程序冻结
- python - 由于需要密码加密,Python Sqlanydb 无法连接到 Sybase
- python - 我想将噪声应用于由 3D numpy 数组描绘的体积
- r - R中带有条件语句的线性回归
- python - Keras:将 MDN 层添加到 LSTM 网络
- assembly - 系统调用在 virtualbox 中运行的 Linux debian 64 位的汇编中不起作用
- json - 在 Swift 4 中转换为 Codable 之前检查 JSON 对象键