Typescript 带有“Type'”的打字脚本拒绝;{}[]和#x27;不可分配给类型';编号'`
假设我创建了一个简单的函数,将其输入加倍Typescript 带有“Type'”的打字脚本拒绝;{}[]和#x27;不可分配给类型';编号'`,typescript,typescript-typings,ramda.js,definitelytyped,Typescript,Typescript Typings,Ramda.js,Definitelytyped,假设我创建了一个简单的函数,将其输入加倍 > let f1: (x: number) => number = x => x * 2; > .type f1 let f1: (x: number) => number 如果我想取第一个值并将其加倍,我可以选择 let f2 = R.pipe( R.take(1), f1 ); let f2 = R.pipe( R.head, f1 ); 这两项工作都是在TypeScript之外进行的。然而,我得到了TypeScri
> let f1: (x: number) => number = x => x * 2;
> .type f1
let f1: (x: number) => number
如果我想取第一个值并将其加倍,我可以选择
let f2 = R.pipe( R.take(1), f1 );
let f2 = R.pipe( R.head, f1 );
这两项工作都是在TypeScript之外进行的。然而,我得到了TypeScript
> let f2 = R.pipe( R.take(1), f1 );
[eval].ts(6,29): error TS2345: Argument of type '(x: number) => number' is not assignable to parameter of type '(x: {}[]) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{}[]' is not assignable to type 'number'.
> let f2 = R.pipe( R.head, f1 );
[eval].ts(6,26): error TS2345: Argument of type '(x: number) => number' is not assignable to parameter of type '(x: string) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type 'string' is not assignable to type 'number'.
我做错了什么。我甚至不知道怎么读
而且,我看不出是什么原因导致了字符串
(我在任何地方都看不到
字符串)。这背后的一般问题是,TypeScript在使用高阶泛型函数时做得很差:
在大多数情况下,当您将一个泛型函数(如R.take(n)
或R.head
)传递到另一个函数(如R.pipe
)时,TypeScript将自动推断它们,而不是保留自由的泛型类型参数。很多时候,它将这些参数推断为{}
,它是空类型
在使用R.head
的第二个示例中,它推断字符串,因为R.head
实际上是用两个重载定义的:
// from ramda/index.d.ts
head<T>(list: ReadonlyArray<T>): T | undefined;
head(list: string): string;
这背后的一般问题是,TypeScript在使用高阶泛型函数时表现非常糟糕:
在大多数情况下,当您将一个泛型函数(如R.take(n)
或R.head
)传递到另一个函数(如R.pipe
)时,TypeScript将自动推断它们,而不是保留自由的泛型类型参数。很多时候,它将这些参数推断为{}
,它是空类型
在使用R.head
的第二个示例中,它推断字符串,因为R.head
实际上是用两个重载定义的:
// from ramda/index.d.ts
head<T>(list: ReadonlyArray<T>): T | undefined;
head(list: string): string;
你说到了每一点,我真的很喜欢你把github问题联系起来。回答得很好。事实上,我很想知道为什么take(1)
也是这样工作的(我可能会要求跟进,因为我对那里的历史有点感兴趣)。我将在这一个上掷下一个悬赏(并在稍后将其标记为已接受),以帮助您通过堆栈溢出的等级。别动!你认为flow能更好地处理这个问题吗?我对Flowtype没有太多的经验或知识,但它确实能正确地处理这个问题。最近合并了一个PR,这可能会使TypeScript在将来更好地推断这些类型:你抓住了每一点,我真的很喜欢你将github问题联系起来。回答得很好。事实上,我很想知道为什么take(1)
也是这样工作的(我可能会要求跟进,因为我对那里的历史有点感兴趣)。我将在这一个上掷下一个悬赏(并在稍后将其标记为已接受),以帮助您通过堆栈溢出的等级。别动!你认为flow能更好地处理这个问题吗?我对Flowtype没有太多的经验或知识,但它确实能正确地处理。最近合并了一个PR,这可能会使TypeScript在将来更好地推断这些类型:
// from ramda/index.d.ts
head<T>(list: ReadonlyArray<T>): T | undefined;
head(list: string): string;
let f4 = R.pipe<number[], number, number>( R.head, f1 );
// from ramda/index.d.ts
take<T>(n: number): {
(xs: string): string;
(xs: ReadonlyArray<T>): T[];
};