typescript - 打字稿:允许泛型类型仅是具有“字符串”属性的对象
问题描述
我想知道是否可以在 TS 中强制执行泛型的属性类型。我只想允许传递具有“字符串”属性的对象类型的泛型。例如,如果传递的通用接口包含数字或符号属性,则会引发错误。
这是我尝试并评论了我正在寻找的行为的POC :
class Test<T extends {[key: string]: any}>{
private data: T;
public getValue<K extends keyof T>(key: K): T[K] {
return this.data[key];
}
}
// the property is a string = ok
const okay = new Test<{ "aString": string }>();
// the property is a number = should raise an error
const shouldFail = new Test<{ 0: string }>();
解决方案
如果对象有字符串索引,我们也可以按数字索引对象,因此编译器没有理由抛出错误数字键。这是设计使然。
declare let skeys: { [key: string]: number }
let v1 = skeys[0] // number
let v2 = skeys["0"] // number
declare let nkeys: { [key: number]: number }
let v3 = nkeys[0] // number
let v4 = nkeys["0"] // error
declare let snkeys: {
[key: number]: number;
[key: string]: string | number // The string index has to contain any value reuned by the number index
}
let v5 = snkeys[0] // number
let v6 = snkeys["0"] // string| number
如果对象包含任何非字符串键,我们可以使用条件类型来强制出错。该错误不会很漂亮,但它是可读的并且可以完成工作:
class Test<T extends { [key: string]: any } & (keyof T extends string ? {} : "T must obnly have string keys") >{
private data!: T;
public getValue<K extends keyof T>(key: K): T[K] {
return this.data[key];
}
}
// the property is a string = ok
const okay = new Test<{ "aString": string }>();
// Error: Type '{ 0: string; }' does not satisfy the constraint '{ [key: string]: any; } & "T must only have string keys"'.
const shouldFail = new Test<{ 0: string }>();
笔记
T
如果您对简单object
类型的值没有任何其他约束也可以
class Test<T extends object & (keyof T extends string ? {} : "T must only have string keys") >{ }
推荐阅读
- ruby-on-rails - 如何在完全隔离的 chrome 实例中运行 rails 应用程序?
- azure - 如何在逻辑应用程序中计算以小时为单位的日期差异
- typescript - 尝试使用 tsyringe 和 typeorm 进行依赖注入时遇到问题
- class - 为什么嵌套类使包含类可以访问子类的受保护数据?
- python - 使用 Pandas 为靠得太近的数字添加缓冲区
- vb.net - 使用时间跨度值更改日期的时间部分
- excel - INDEX MATCH 基于多个标准。一个是 FIND,另一个是 Max date
- python - 基于groovy代码生成HmacSHA256到Python中
- c++ - 无法从 decltype 中获取指向成员函数的指针
- android - 有线问题,RecyclerView 在某些特定的三星 Galaxy 设备上不显示项目