使用“clamped”类型创建通用函数的版本

时间:2016-08-01 16:18:55

标签: generics typescript

假设我有一个函数返回一个由泛型参数化的类型。我将要使用这个功能很多。大多数时候我会使用一种特定的类型 - 比如number。为方便起见,最好只为数字设置此函数的别名。

玩具示例:

function arrayMaker<T>() : Array<T> {
    return new Array<T>();
}
let numericalArrayMaker: () => Array<number> = arrayMaker<number>;

但TypeScript编译器抱怨最后一行,认为我正在为numericArrayMaker分配类型number[]

我很困惑为什么会失败,因为我可以为变量分配一个函数(没有泛型类型):

function foo() { return 0; }
let foo2 = foo;

...我可以为变量指定一个类型(带有泛型):

type numericalArray = myArray<number>;

我正在尝试做什么不同的语法?

(我知道我可以使用返回“arrayMakers”的工厂函数来使我的示例工作,但这会变得更加冗长,如果我的函数接受参数,会导致一些代码重复。)

1 个答案:

答案 0 :(得分:2)

您需要做的就是将arrayMaker的引用保存到另一个具有所需类型的变量:

function arrayMaker<T>() : Array<T> {
    return new Array<T>();
}

let numericalArrayMaker: () => Array<number> = arrayMaker
let mynums: number[] = numericalArrayMaker();

如果您没有使用功能签名,则不能使用泛型,例如:arrayMaker<number>,它没有任何意义。

修改

我不确定为什么编译器不会抱怨

let numericalArrayMaker: (string) => number[] = arrayMaker;

这可能是一个错误,或者可能有一个更好的解释让我望而却步,如果你确实打开了一个问题,请将网址发布为评论,因为我想继续发布。

你可以解决这个问题:

type ArrayMaker<T> = (value: T) => T[];

let numericalArrayMaker: ArrayMaker<number> = arrayMaker;
let mynums: number[] = numericalArrayMaker("foo"); // error

至于为什么:

let a = arrayMaker<number>;

没有意义,是你要将arrayMaker函数的引用分配给变量a,但是js中没有generics这样的东西所以&# 39;对arrayMaker<number>没有意义。
你想要的是铸造:

let a = arrayMaker as arrayMaker<number>;

也许课程会更清晰:

class A<T> {}

let a1 = A<number>; // error
let a2 = A as A<number>; / ok

这适用于:

type numericalArray = myArray<number>;

因为在这里你处理myArray的类型而不是实际的功能。

这带来了我个人相信的其他东西:
不要在打字稿的打字稿中写代码,也就是说,如果您编写的编译代码没有做任何事情,那么只是为了得到你的编译而写的,那么这可能是一个坏主意。 / p>

我认为最好的选择是:

let mynums: number[] = arrayMaker(4);