[英]Type declaration of a generic `map` function in TypeScript
在typescript-exercises 的练习 #14 中,您可以注释以下函数:
export function map(mapper, input) {
if (arguments.length === 0) {
return map;
}
if (arguments.length === 1) {
return function subFunction(subInput) {
if (arguments.length === 0) {
return subFunction;
}
return subInput.map(mapper);
};
}
return input.map(mapper);
}
我尝试使用泛型对其进行严格输入,但失败了:
type Apply<In, Out> = (element: In) => Out;
declare function subFunction<In2, Out2>(subInput: In2[]): Out2[];
declare function subFunction(): typeof subFunction;
export function map<In, Out>(): typeof map;
export function map<In, Out>(mapper: Apply<In, Out>): typeof subFunction;
export function map<In, Out>(mapper: Apply<In, Out>, input: In[]): Out[];
export function map<In, Out>(mapper?: Apply<In, Out>, input?: In[]): ((typeof map) | (typeof subFunction) | Out[]) {
if (mapper === undefined) {
return map;
}
if (input === undefined) {
// Line 61 (the error) ahead
return function subFunction(subInput?: In[]): ((typeof subFunction) | Out[]) {
if (subInput === undefined) {
return subFunction;
}
return subInput.map(mapper);
};
}
return input.map(mapper);
}
错误是:
index.ts(61,9): error TS2322: Type '(subInput?: In[] | undefined) => Out[] | ...' 不能分配给类型 '{ <In2, Out2>(subInput: In2[]): Out2[]; (): 子函数类型; } | { <In, Out>(): typeof map; <In, Out>(映射器: Apply<In, Out>): { <In2, Out2>(subInput: In2[]): Out2[]; (): 子函数类型; }; <In, Out>(mapper: Apply<...>, input: In[]): Out[]; } | 出去[]'。 输入 '(subInput?: In[] | undefined) => Out[] | ...' 不能分配给类型 '{ <In2, Out2>(subInput: In2[]): Out2[]; (): 子函数类型; }'。 输入“输出[] | ((subInput?: In[] | undefined) => Out[] | ...)' 不能分配给类型 'any[]'。 输入 '(subInput?: In[] | undefined) => Out[] | ...' 缺少类型 'any[]' 的以下属性:pop、push、concat、join 和另外 25 个。
当我将subFunction
@ line 61 的返回类型更改为any
时,错误消失了。
我究竟做错了什么?
我认为问题在于使用declare
关键字。 我不确定问题出在哪里,但是这里没有正确使用关键字。 它应该用于通知编译器存在名为subFunction
的函数,但事实并非如此,因为subFunction
实际上是在map
中声明的。
您可以通过将声明替换为我在此处称为SubMap<In, Out>
的另一种type
来解决此问题。
type Apply<In, Out> = (element: In) => Out;
type SubMap<In, Out> = (subInput?: In[]) => SubMap<In, Out> | Out[];
export function map<In, Out>(): SubMap<In, Out>;
export function map<In, Out>(mapper: Apply<In, Out>): SubMap<In, Out>;
export function map<In, Out>(mapper: Apply<In, Out>, input: In[]): Out[];
export function map<In, Out>(mapper?: Apply<In, Out>, input?: In[]): typeof map | SubMap<In, Out> | Out[]
{
if (mapper === undefined)
{
return map;
}
if (input === undefined)
{
return function subFunction(subInput?: In[]): SubMap<In, Out> | Out[]
{
if (subInput === undefined)
{
return subFunction;
}
return subInput.map(mapper);
};
}
return input.map(mapper);
}
另一种选择是在map
之外实际创建subFunction
,尽管这需要一些重构。
type Apply<In, Out> = (element: In) => Out;
function subFunction<In, Out>(mapper: Apply<In, Out>): typeof subFunction;
function subFunction<In, Out>(mapper: Apply<In, Out>, subInput: In[]): typeof subFunction | Out[];
function subFunction<In, Out>(mapper: Apply<In, Out>, subInput?: In[]): typeof subFunction | Out[]
{
if (subInput === undefined)
{
return subFunction;
}
return subInput.map(mapper);
}
export function map<In, Out>(): typeof map;
export function map<In, Out>(mapper: Apply<In, Out>): typeof subFunction;
export function map<In, Out>(mapper: Apply<In, Out>, input: In[]): Out[];
export function map<In, Out>(mapper?: Apply<In, Out>, input?: In[]): typeof map | typeof subFunction | Out[]
{
if (mapper === undefined)
{
return map;
}
if (input === undefined)
{
return subFunction(mapper);
}
return input.map(mapper);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.