【问题标题】: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 }>();

【问题讨论】:

标签: typescript


【解决方案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&lt;T extends object &amp; (keyof T extends string ? {} : "T must only have string keys") &gt;{
  • @FlavienVolken 是的,这也可以。索引签名将有助于约束对象的值
  • @FlavienVolken 添加了您的建议 :)
猜你喜欢
  • 2021-12-06
  • 1970-01-01
  • 2022-10-25
  • 2019-03-12
  • 2021-06-09
  • 1970-01-01
  • 2020-05-25
  • 2021-12-30
  • 2019-10-15
相关资源
最近更新 更多