export {}
interface Types {
A: 'A'
B: 'B'
}
type GetType = <K extends keyof Types> (k: K) => K
let f: GetType = k => k
f('A')
type ReturnType = <K extends keyof Types> () => K
let f2: ReturnType = () => 'A'
^^
为何 f2 处会出错:
[ts] 'f2' is declared but its value is never read.
[ts]
Type '() => "A"' is not assignable to type 'ReturnType'.
Type '"A"' is not assignable to type 'K'.
let f2: ReturnType
1
noe132 2018-09-30 23:27:15 +08:00
我的理解
K 是类型内的一个类型参数,相当于一个局部类型 K 这个类型如果没有从参数中捕获,直接使用的话除了 any 其他类型都不是 K,因为没有类型是 K。 因为 K 并不等于 keyof Types type TypeKeys = keyof Types type ReturnType = () => TypeKeys let f2: ReturnType = () => 'A' 这样就没有问题。 |
3
noe132 2018-10-01 14:04:53 +08:00
K 是一个泛型的参数,并不是一个确定的类型
K extends keyof Types 只是对这个泛型的一个约束 类型参数 K 要么从函数入参确定,要么定义类型为泛型,从泛型的类型参数中获取 你这两个都没有,K 相当于是一个未知类型。 |
4
noe132 2018-10-01 14:10:24 +08:00
你把 K extends key of Types 改成 K extends any 都没有用的。因为没有类型是 K。
|
5
banxi1988 2018-10-01 16:12:35 +08:00
我尝试了一下。
首先使用一个有意思的 Interface 稍微调整了一下代码。 ```ts interface Person { name: string; age: number; } type PersonProp = keyof Person; type PersonPropIdentity = <K extends PersonProp>(prop: K) => K; let personPropIdentity: PersonPropIdentity = k => k; type FunType1 = <K extends PersonProp>() => K; let f2: FunType1 = () => { return "age"; }; ``` 此时 FunType1 展开之后其实是 : type FunType1 = <K extends "name" | "age">() => K 此时 f2 返回 "age" 应该是符合 K 类型的限定的。 因此我倾向为认为这是 TypeScript 类型系统一个 Bug. 可以给 TypeScript 反馈一下。 另外在这种情况下主要是 K extends 影响了类型的推断,不用 K extends 即可。 如下代码是没有编译错误的。 ```ts type FunType2 = () => PersonProp; let f3: FunType2 = () => { return "age"; }; ``` 而且在 f3 的函数声明来看使用 K extends PersonProp 是没有意义的。 |