打字稿:允许泛型类型仅是具有“字符串”属性的对象
Posted
技术标签:
【中文标题】打字稿:允许泛型类型仅是具有“字符串”属性的对象【英文标题】:Typescript: allow a generic type to only be an object with 'string' properties 【发布时间】:2019-03-10 14:35:21 【问题描述】:我想知道是否可以在 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 >();
【问题讨论】:
相关:***.com/questions/13315131/… @bugs 情况不同,11315131 不包括扩展另一个接口。 【参考方案1】:如果对象有字符串索引,我们也可以按数字索引对象,因此编译器没有理由抛出错误数字键。这是设计使然。
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") >
【讨论】:
+1 我什至建议:class Test<T extends object & (keyof T extends string ? : "T must only have string keys") >
@FlavienVolken 是的,这也可以。索引签名将有助于约束对象的值
@FlavienVolken 添加了您的建议 :)以上是关于打字稿:允许泛型类型仅是具有“字符串”属性的对象的主要内容,如果未能解决你的问题,请参考以下文章
打字稿:类型 ConstructorParameters 不接受泛型