打字稿类型映射以期望每个属性都是给定类型的对象

时间:2017-02-06 15:02:19

标签: typescript

在typescript中我有一个类型为X的接口。我有一个方法需要一个具有任意数量属性的对象,但每个属性必须是X类型。例如,这两个属性都可以作为参数传递:

interface IJays {
    jim: X;
    jone: X;
    jan: X;
}

interface IBees {
    bill: X;
    bob: X;
    betty: X;
}

但这不是作为参数传递的有效类型:

interface ISees {
    claude: X;
    carol: boolean;
    clem: number;
}

在这种情况下,属性的名称也很重要(它们会在处理中使用)。

如果我可以使用不同的数据结构会很棒,但这是来自某些API的结构。我也没有所有接口的有限列表。随着项目的增长,将有任何数量的接口遵循这种模式。

目前,我将此属性输入为" any",但我真的希望将其作为特定类型以防止将来出现错误(这是一种容易出错的事情。未来的)。

有没有办法将此指定为打字稿中的类型?本质上,一个任意对象,该对象的每个属性都是特定类型?也许使用新的Mapped Types功能?

1 个答案:

答案 0 :(得分:1)

我认为你有两种选择:

(1)具有通用值类型的函数:

interface IJays {
    jim: string;
    jone: string;
    jan: string;
}

interface IBees {
    bill: string;
    bob: string;
    betty: string;
}

interface ISees {
    claude: string;
    carol: boolean;
    clem: number;
}

function fn<T, V>(o: { [key in keyof T]: V }) { /* ... */ }

let a: IJays = { jim: "jim", jone: "jone", jan: "jan" };
fn<IJays, string>(a); // fine

let b: IBees = { bill: "bill", bob: "bob", betty: "betty" };
fn<IBees, string>(b); // fine

let c: ISees = { claude: "claude", carol: true, clem: 3 };
fn<ISees, string>(c); // error

code in playground

但正如您所看到的,在调用函数时,您必须指定通用约束,因为编译器无法推断它们。
如果你不想这样做那么选项#2。

(2)每种类型都有不同的功能:

function fnString<T>(o: { [key in keyof T]: string }) { /* ... */ }
function fnNumber<T>(o: { [key in keyof T]: number }) { /* ... */ }

let a: IJays = { jim: "jim", jone: "jone", jan: "jan" };
fnString(a); // fine

let b: IBees = { bill: "bill", bob: "bob", betty: "betty" };
fnString(b); // fine

let c: ISees = { claude: "claude", carol: true, clem: 3 };
fnString(c); // error

code in playground

这里编译器可以推断出通用约束,但是你需要为每种类型提供不同的函数。