这是某些功能lab的实际(简化)示例

const lab = <
  T extends Something,
  K extends keyof T
>(k: T[K] extends (...args: any[]) => any ? K : never) => {
  return ({} as T)[k];
}

const test = lab<Something, 'fn'>('fn')

type Something = {
  str: string,
  num: number
  bool: boolean,
  fn: (a: number, b: number) => number,
}

它的工作效果如预期的那样.但通过下面的屏幕,我展示了我也想要的东西,但不明白为什么这是不可能的.

下面的一些屏幕肯定是一般类型是有效的.

allow str in generic placeholder as key of Something but error with argument ... so aka works
enter image description here

event if argument become str also error ... so aka works
enter image description here

allow fn and tip it in argument ... good! enter image description here

yes, this is only one correct variant and no errors! works
enter image description here

But why it can't tip me fn at once? Or at least any of the Something keys aka str, num...?

enter image description here

推荐答案

当您调用lab()函数时,您正在为类型参数Kgeneric类型参数寻找IntelliSense to auto-suggest a completion list. 但TypScript的Intelligence Sense支持不提供此类完成. 您可以通过一个最小的例子来展示这一点,例如:

const f = <K extends "x" | "y">() => 0;
f<"x">() // okay
f<"">()
// ^ abc "A"
// ^ abc "a"
// ^ abc "All"
// ^ abc "all"
// ...

在这里,Intelligence Sense推荐"x""y"应该非常容易,但您会获得TypScript所知道的所有字符串字面量的完整列表.

长期以来,microsoft/TypeScript#28662处存在一个开放功能请求,要求此功能.如果您想看到它发生,您可能想go 那里并给它一个警告.但在实现之前,您需要放弃或解决它.


如果您愿意使用values而不是types,那么您可以使用curry您的函数,因此您手动指定T的类型参数,然后返回的函数将将K限制为您想要支持的类型,然后您就不会手动指定K;相反,您只需调用具有类型K的值的函数,即可获得函数参数的Intelligence完成列表:

const lab = <T extends Something>() =>
    <K extends { [P in keyof T]:
        T[P] extends (...args: any) => any ? P : never
    }[keyof T]>(
        k: K
    ) => { return ({} as T)[k]; }


const test = lab<Something>()("") // <--
//                            ^🔧 fn

在这里,您指定了Something,然后获得fn作为返回函数的建议输入.

只有当您实际上需要K才能是通用的时,才需要咖喱;您可能不会:

const lab = <T extends Something>(k: { [P in keyof T]:
    T[P] extends (...args: any) => any ? P : never
}[keyof T]) => { return ({} as T)[k]; }

const test = lab<Something>("") // <--
//                          ^🔧 fn

但这有点偏离了所问问题的答案,即:如果没有Microsoft/Typescript#28662,您想要的完成列表是不可能的.

Playground link to code

Typescript相关问答推荐

如何根据参数的值缩小函数内的签名范围?

调用另一个函数的函数的Typescript类型,参数相同

如何根据数据类型动态注入组件?

界面中这种类型的界面界面中的多态性

在类型内部使用泛型类型时,不能使用其他字符串索引

找不到带名称的管道''

如何修复正在处理类型但与函数一起使用时不处理的类型脚本类型

如果请求是流,如何等待所有响应块(Axios)

Material UI / MUI系统:我如何告诉TypeScript主题是由提供程序传递的?

在分配给类型的只读变量中维护const的类型

为什么有条件渲染会导致material 自动完成中出现奇怪的动画?

是否可以从函数类型中创建简化的类型,go 掉参数中任何看起来像回调的内容,而保留其余的内容?

如何使用模板继承从子组件填充基础组件的画布

使用条件类型的类型保护

根据类型脚本中的泛型属性 Select 类型

自动通用回调

如何通过转换器类继承使用多态将对象从一种类型转换为另一种类型

为什么TypeScrip假定{...省略类型,缺少类型,...选取类型,添加&>}为省略类型,缺少类型?

TypeScript:方法获胜';t接受较窄类型作为参数

为什么TS条件返回要求不明确的强制转换而不是精确的强制转换?