如何使用带有 TypeScript 的 keyof 访问器定义返回类型?

Rea*_*lar 0 javascript generics casting typescript

是否可以创建一个keyof用于访问对象属性的函数,并让 TypeScript 推断返回值?

interface Example {
    name: string;
    handles: number;
}

function get(n: keyof Example) {
   const x: Example = {name: 'House', handles: 8};
   return x[n];
}

function put(value: string) {

}

put(get("name"));
// ^^^ Error: Argument of type 'string | number' is not assignable to parameter of type 'string'
Run Code Online (Sandbox Code Playgroud)

TypeScript 正在所有允许的类型合并在一起,但是当使用值调用函数时,"name"它不会推断类型是string

我可以通过转换类型来解决这个问题。

put(get("name") as string);
Run Code Online (Sandbox Code Playgroud)

有没有办法在不铸造的情况下做到这一点?

jca*_*alz 5

当然,你只需要get 通用,这样它就不会返回所有可能的输出类型的联合:

function get<K extends keyof Example>(n: K) {
  const x: Example = { name: "House", handles: 8 };
  return x[n];
}
Run Code Online (Sandbox Code Playgroud)

现在推断签名为:

// function get<K extends "name" | "handles">(n: K): Example[K]
Run Code Online (Sandbox Code Playgroud)

其中,返回类型Example[K]是一种查找类型,表示在对Examplewith 键进行索引时获得的类型K

当您调用它时,K如果它可以是,则推断为字符串文字类型:

get("name"); // function get<"name">(n: "name"): string
Run Code Online (Sandbox Code Playgroud)

并且Example["name"]等价于string。所以现在你的电话按需要工作:

put(get("name")); // okay
Run Code Online (Sandbox Code Playgroud)

希望有帮助。祝你好运!

代码链接