使用extends keyof作为泛型类型时,“never”类型出错

时间:2017-07-15 22:35:57

标签: typescript lenses

我在打字稿中的代码:

class Author {
  id: number;
}
type Getter<S, A> = (obj: S) => A;

function propGetter<S, K extends keyof S>(prop: K): Getter<S, S[K]> {
  return o => o[prop];
}
const _id: Getter<Author, number> = propGetter('id');

我收到了错误:

Argument of type '"id"' is not assignable to parameter of type 'never'.

Code in typescript playground

据我了解,类型K应该是S类型的键的字符串。它是如何统一到永远的?这是因为使用映射类型作为通用参数?

1 个答案:

答案 0 :(得分:2)

当您只传递K时,编译器无法推断出const _id: Getter<Author, number> = propGetter<Author, "id">('id'); 的类型。
如果你这样做会有效:

S

或者,如果您更改函数以接收function propGetter<S, K extends keyof S>(obj: S, prop: K): Getter<S, S[K]> { return o => o[prop]; } const _id: Getter<Author, number> = propGetter(new Author(), 'id'); 的实例(然后它将推断类型):

function propGetter<S>(prop: keyof S): Getter<S, S[typeof prop]> {
    return o => o[prop];
}
const _id = propGetter<Author>('id'); // type of _id is Getter<Author, number>

修改

经过一番思考,你可以这样做:

function propGetter<S>(prop: keyof S): Getter<S, any> {
    return o => o[prop];
}

const _id = propGetter<Author>('id') as Getter<Author, number>;
// or
const _id: Getter<Author, number> = propGetter<Author>('id');

第二次编辑

我不喜欢在编译的js中添加无用的代码,只是为了让编译器满意 这是一个这样的情况,我认为最好的解决方案是这样的:

poll()

通过这种方式,您可以以不那么冗长的方式获得类型安全性,并且没有任何内容添加到不属于那里的js中。