如何为映射类型添加索引签名? [英] How do I add an index signature for a mapped type?

查看:19
本文介绍了如何为映射类型添加索引签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有接口

interface X {
   a: string;
   b: number;
   c: boolean;
}

和一个函数

function values(x: X) {
   return Object.keys(x).map(s => x[s])
}

当我启用 typescript 的 strict 标志时,我收到错误元素隐式具有 'any' 类型,因为类型 'X' 没有索引签名".所以为了明确起见,我可以在 X 的定义中添加一个索引签名

When I enable typescript's strict flag I get the error "Element implicitly has an 'any' type because type 'X' has no index signature". So to make it explicit, I can just add an index signature to the definition of X

[key: string]: any;

简单易行.

但是,如果 I X 现在是映射类型:

However if I X is now a mapped type instead:

type X<T> = {
  [P in keyof T]: string;
}

我有这个功能

function values<T>(x: X<T>) {
  return Object.keys(x).map(s => x[s])
}

我应该在哪里添加索引签名?有什么方法可以使这一点明确而不诉诸于像 Object.keys(x).map(s => (x as any)[s])

where am I supposed to add the index signature? Is there any way to make this explicit without resorting to doing something gross like Object.keys(x).map(s => (x as any)[s])

推荐答案

您可以:

interface X {
    a: string;
    b: number;
    c: boolean;
    [key: string]: X[keyof X];
}

X[keyof X] 的结果现在将是 (string | number | boolean),这比 any 效果更好,因为您的函数的返回将是 (string | number | boolean)[].

The result of X[keyof X] will now be (string | number | boolean), which works even better than any because the return of your function will be (string | number | boolean)[].

示例

适用于这两个示例的另一种方法是:

Another way that should work with both examples is:

function values(x: X) {
    const keys = Object.keys(x) as (keyof X)[];
    return keys.map(s => x[s]);
}

不漂亮,但至少比 (x as any) 更有类型.

Not pretty, but at least more typed than (x as any).

当然也可以通用:

function values<T>(x: T) {
    const keys = Object.keys(x) as (keyof T)[];
    return keys.map(s => x[s]);
}

这篇关于如何为映射类型添加索引签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆