繁体   English   中英

如何表达通用约束以具有特定类型的动态属性

[英]How to express a generic constraint to have a dynamic property of a specific type

我正在构建一个提供通用实用程序 function 的库。

这个 function 应该对传入的 object 的属性之一做一些事情,但属性名称也是用户提供的参数。

为了简化,想象一下:

type T1 = {
    id: string;
    foo: number;
    bar: string[];
}
const sampleData1: T1 = { bar: ["a"], foo: 42, id: "myid" }
const doSomething = <F>(somearg: F, path: keyof F) => {
    console.log(somearg[path]);
}

doSomething(sampleData1, "id");

output 是我所期望的: "myid"

但是,我只想在我的 function 中使用字符串。 但实际代码也适用于:

type T3 = {
    wrong: number;
    value: number;
}
const sampleData3 : T3 = { value : 100, wrong : 5 }

const doSomething = <F>(somearg: F, path: keyof F) => {
    console.log(somearg[path]);
}

doSomething(sampleData3, "wrong");

此代码有效并发出5 但我实际的 function 应该只适用于字符串。

有没有办法表达F泛型类型以使动态名称属性只是一个字符串?

我试过了:

const doSomething = <F extends { [path] : string }>(somearg: F, path: keyof F) => {

    console.log(somearg[path]);

}

但语法无效:

A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
Cannot find name 'path'.

如何解决?

仅供参考:我运行 TS 4.5.5。 我实际的 function 处于依赖关系中,并且消费代码存在于多个应用程序中,具有非常不同的业务需求。

实用程序 function 也可以在同一个 object 上调用多次,但属性名称不同。

TS 操场上的完整复制

在这种情况下,索引 object 类型的语法是{ [key in KeyType]: valueType }

在您的情况下,您希望约束F以使路径具有字符串值,但您不关心 rest。

您可以使用 2 种通用类型:1 用于路径,1 用于 object:

const doSomething = <P extends string, F extends { [p in P]: string }>(somearg: F, path: P) => {}

它正确拒绝了第三个样本:

doSomething(sampleData1, "id");
doSomething(sampleData2, "key");
doSomething(sampleData3, "wrong"); // Error: Type 'number' is not assignable to type 'string'.

游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM