所以在这个基本的例子中(tryflow):
// basic identity function example with generic type
type Foo = { prop: number};
type Bar = { prop: string };
const foo: Foo = { prop: 1 };
const bar: Bar = { prop: 'a' };
function identity<T>(same: T): T {
return same;
}
// here identity acts as (Foo) => Foo
const foo2: Foo = identity(foo);
// and here it's (Bar) => Bar
const bar2: Bar = identity(bar);
我的identity
函数,使用泛型,取任何类型的函数。由于参数与之绑定,T
首先成为Foo
,然后成为Bar
。
我想要的是一个返回泛型函数的高阶函数。我可以编写一个使用泛型(tryflow)的高阶函数:
type IdentityFunction = <T>(self: T) => T;
// error here
const baseId: IdentityFunction = (same) => same;
// ^ Cannot assign function to
// `baseId` because `T` [1] is
// incompatible with `T` [2] in
// the return value.
type Foo = { prop: number};
type Bar = { prop: string };
const foo: Foo = { prop: 1 };
const bar: Bar = { prop: 'a' };
function makeIdentity(func: IdentityFunction): IdentityFunction {
return func;
}
const identity: IdentityFunction = makeIdentity(baseId);
const foo2: Foo = identity(foo);
const bar2: Bar = identity(bar);
对我来说,这种方法最有意义。老实说,我不确定为什么会收到这个错误。 T
如何与自己不相容?是因为类型永远不会明确地应用于T
吗?它在某种程度上是不确定的,所以它不能用于任何东西?但那么,这不是泛型的全部意义吗?无论如何,我确定我只是错过了类型系统的一些微妙之处,或者我可能会以错误的方式解决这个问题。任何帮助表示赞赏。
答案 0 :(得分:1)
您需要一般性地键入您的baseID函数,以便Flow知道您期望的参数和返回类型。在尝试弄清楚真正做什么的baseId函数时,Flow似乎没有使用IndentityFunction的类型。
(Try)
type IdentityFunction = <T>(self: T) => T;
// no more error
const baseId: IdentityFunction = <S>(same: S): S => same;
type Foo = { prop: number};
type Bar = { prop: string };
const foo: Foo = { prop: 1 };
const bar: Bar = { prop: 'a' };
function makeIdentity(func: IdentityFunction): IdentityFunction {
return func;
}
const identity: IdentityFunction = makeIdentity(baseId);
const foo2: Foo = identity(foo);
const bar2: Bar = identity(bar);
您可以将baseId的实例化简化为:
const baseId = <S>(same: S): S => same;
然后流动still understands这里发生了什么。
这种行为有点令人困惑,我想知道是否有充分的理由。你会认为它可以采取左侧的内容并将其应用于右侧的功能(特别是在像这样的简单情况下)。也许它与流程如何看待正确的表达有关?如果有其他人有想法,我很乐意听到。
无论哪种方式,我倾向于避免在声明的左侧声明函数的类型。不作为规则,我很少想在函数本身之外的某处声明函数的类型。