typescript - 如何在泛型类中编写“K extends keyof T”然后使用 K
问题描述
我想创建一个类,它获取一个对象作为类型参数,然后将该类型用作该类中属性的类型,这样我只能设置和获取值,如果该键存在于该对象中。
我创建了一个接口,我们称之为 IStorage。Storage 类应该实现 iStorage 并根据给定对象中是否存在键来存储值。
interface iStorage<T, K extends keyof T> {
getField(k: K): T[K];
setField(k: K, v: string | number | object): T[K];
render(): void;
}
class Storage<T, K extends keyof T> implements iStorage<T, K> {
private fields: { [key: K]: string | number | object };
public getField(k: K): T[k] {
return this.fields[k];
}
public setField(k: K, v: string | number | object): T[k] {
return (this.fields[k] = v);
}
}
let storage = new Storage<{name: string, type: number}>();
我希望存储中的字段与通用定义匹配(我认为是 T[K]),但打字稿说键必须是字符串或数字类型,所以这不能按预期工作。在我的界面中我想说的是,setFormField 的第二个参数也是 T[K]。我还认为,我的类型定义是重复的。Typescript 也希望我给出一个 seconds 参数,这对我来说很有意义,但我不想每次都在函数上编写 K extends keyof T ,也不能将它用作属性类型。
尝试了很多安静,但无法让它工作..实际上我有点迷茫,因为我现在已经尝试了几个小时。以前从来没有用过仿制药,所以请对我温柔一点。:D
希望有人能帮帮我。
解决方案
我不是 100% 确定您的用例,但我倾向于将您的代码更改为以下内容:
interface IStorage<T extends object> {
getField<K extends keyof T>(k: K): T[K];
setField<K extends keyof T>(k: K, v: T[K]): T[K];
render(): void;
}
class Storage<T extends object> implements IStorage<T> {
constructor(private fields: T) { }
render() { }
public getField<K extends keyof T>(k: K) {
return this.fields[k];
}
public setField<K extends keyof T>(k: K, v: T[K]): T[K] {
return (this.fields[k] = v);
}
}
let storage = new Storage({ name: "str", type: 123 });
const str = storage.getField("name");
const num = storage.setField("type", 456);
这里的IStorage
接口只取决于T
对象的类型,个体getField()
和setField()
方法本身就是通用函数,可以作用K
于keyof T
. 泛型类型参数K
不会出现在接口本身上。
我已经改变了Storage
匹配的实现。请注意,我已使构造函数采用类型的值,T
该值存储为私有成员。如果您不想传递初始值,那么您将不得不限制T
为具有所有可选属性的类型(即,使用类似的东西Partial<T>
而不是仅仅T
.)
您可以从上面的代码(或在操场链接中)看到 IntelliSense 是您想要的方式......getField("name")
已知调用会返回 type 的值string
。
好的,希望对你有帮助。祝你好运!
推荐阅读
- typescript - error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'string'
- sql - 如何从表中仅选择字段 1 中的值与字段 2 的至少两个不同值配对的行
- elasticsearch - 匹配查询在 Elasticsearch 中包含正斜杠
- android - 语言环境返回没有国家代码的语言环境
- c++ - qt QWidget::closeEvent 链接问题
- ffmpeg - 通过 LAN 使用 ffmpeg 流式传输?
- java - AWS 拉取所有依赖项
- docker - Docker 多阶段构建随机失败
- powershell - 如何在不使用 API 的情况下获取我的 Google Drive 的可用空间?
- git - Changelog 的自定义 git 合并联合策略