繁体   English   中英

如何在函数调用而不是函数定义中定义泛型类型

[英]How to define a generic type in function calling rather than function defining

我有一个函数function react_forward_ref<P, T>(fn: (props: P, ref: T) => any) { return fn }其中PT无关。

现在我想使用它并使其返回值中的P and T具有某种关系,例如T = Parameters<typeof OBJ[P]>[0] ,所以我写:

const OBJ = {
    a: (_: number) => _,
    b: (_: string) => _,
    c: (_: object) => _,
}
const MyCom = (<P extends keyof typeof OBJ>() => {
    return react_forward_ref<P, Parameters<typeof OBJ[P]>[0]>((props, ref) => null)
})()

我的预期行为是:

const MyCom = function<P extends keyof typeof OBJ>(props: P, ref: Parameters<typeof OBJ[P]>[0]) { return null }

但目前的行为是:

const MyCom = function(props: keyof typeof OBJ, ref: Parameters<typeof OBJ[keyof typeof OBJ]>[0]) { return null }

老问题:

https://www.typescriptlang.org/play?#code/MYewdgzgLgBA8gIQFIwLwwN4FgBQN8wCGAXDABQD6pYArgLYBGApgE4CUaAfDBQDS4EYDUpVLQWASzABzDqm58BBYCKowQDAFZNgUOQv44AvrlwAzGmF0TwMFk0K6KZkCwDuhFgBMK9swB4ABV4YABVOMjMwEQAHFhAYiFJguyYzUlD9IjAATw4MVKgaFjAYKJgTHFxQSFgAWRyAYRA6NHJ-UJgmAA8oJjAvCBgAayYckDMYKByYpgn4ZAis7DwCeyKS1McoZ1cPb180jpDAz0I6Jj6WCH9p2fnEJABtUIBdTieABneyMjiEiAhPxZWgAG1BbFwRjYZEhOAA9PCYBJYBAABYgGigrwwMAgWAxQgQCC4UGXIhtBrNOhkADkhFpIVpUDREiG6Mx2JgdBo0CETAptEYrBCDBosCgQz64KGF2RsGAhFKzAp4ik0lpbAA3KYEUiWWzkUNJNI0VBquA+VSWp82h0ur1+oMRmN5nc5pNHhF-okMkC0skzhcrjd3Q9kC93l9XssKrhrXRPnSGUzJVMmDLuQKUdzebAVYRcfRmCxNUA

const OBJ = {
    a: (_: number) => _,
    b: (_: string) => _,
    c: (_: object) => _,
}

function react_forward_ref<P, T>(fn: (props: P, ref: T) => any) { return fn }

const MyCom = (<T extends keyof typeof OBJ>() => {
    return react_forward_ref<T, Parameters<typeof OBJ[T]>[0]>((props, ref) => null)
})()
// ts works wrong here
let a = MyCom('a', 'this should must be a number, but ts tells me it can be a string');

// ts works right here
const MyCom0 = <T extends keyof typeof OBJ>(props: T, ref: Parameters<typeof OBJ[T]>[0]) => { }
MyCom0('a', 'ts tells me it must be a number')

如果您向 MyCom 提供显式类型,它会按预期工作

// does not compile
let a = MyCom<'a'>()('a', 'this should must be a number, but ts tells me it can be a string')()

react_forward_ref有两个泛型类型声明。

我有一个函数OriginMyCom需要包装在react_forward_ref ,它需要将两个泛型类型声明绑定在一起。

所以我曾经认为需要在react_forward_ref的两个泛型类型之前声明一个泛型类型才能将它们绑定在一起。

但现在,事实证明我可以:

const OBJ = {
  a: (_: number) => _,
  b: (_: string) => _,
  c: (_: object) => _,
}

function react_forward_ref<P, T>(fn: (props: P, ref: T) => any) { return fn }

const OriginMyCom = <P extends keyof typeof OBJ>(p: P, ref: (typeof OBJ)[P]) => null;

const ForwardedMyCom = react_forward_ref(OriginMyCom);

那是因为Generic Type 是 generic 有点像let a = 123; 其中generic typeareal type123 这就像left value and right value 我们必须注意到它。

因此,要将两个泛型类型绑定在一起,我们应该将泛型类型声明为两个泛型类型之后而不是之前的关系。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM