当前位置: 首页 > 知识库问答 >
问题:

Typescript:允许泛型类型仅为具有“字符串”属性的对象

邵昆琦
2023-03-14

我想知道在TS中是否可以强制泛型的属性类型。我只允许传递具有“string”属性的对象类型的泛型。例如,如果传递的泛型接口将包含数字或符号属性,则引发错误。

以下是我尝试过并评论过的行为的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 }>();

共有1个答案

汤弘文
2023-03-14

如果对象有一个字符串索引,我们也可以按数字索引对象,因此编译器没有理由抛出错误号。这是故意的。

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的值没有任何其他约束,一个简单的对象类型也可以工作

class Test<T extends object & (keyof T extends string ? {} : "T must only have string keys") >{ }
 类似资料:
  • 我正在尝试实现这样一个方法,它接受一个关键参数,该参数要么是要么是可索引类型接口的实例。实现如下所示: Typescript给出块的以下错误: [ts]“IValidationContextIndex”仅引用类型,但在此处用作值。 有什么办法解决这个问题吗? 对于大多数接口,我认为可以添加属性(;),但这在本例中不起作用,因为该接口是可索引类型的接口....

  • 当我使用Jackson ectivtMapper将有效负载序列化为字符串值时,我很难获取要维护的泛型属性的类型信息。 我想要达到的结果如下。 我实际得到的结果如下(注意TestClassA缺少@type信息)。 我使用的测试是: “test JSON编组”测试中有两个版本。注释掉的版本和未注释的版本都会产生完全相同的结果。 第二个测试验证TestClassA本身是否生成了正确的类型信息。 只有当包

  • (沙盒) 获取此错误: 类型“number”不可分配给类型“T”“number”可分配给“T”类型的约束,但“T”可以用约束{}的不同子类型实例化。(2322)输入。ts(1,26):预期类型来自此签名的返回类型。 我希望typescript能够自动推断T为数字,然后直接使用它。为什么它在抱怨?写这样的东西的正确方法是什么?谢谢

  • 我试图在打字稿中使用泛型,这样泛型参数将被用作索引来调用存储在对象中的函数。 我收到的错误是: [ts]不能调用类型缺少调用签名的表达式。类型'((变量:{插入ID:数字;})= 或 “QueryInput[T]”类型的参数不能分配给“{insertId:number;”类型的参数 下面是复制该问题的示例代码: 似乎Typescript引擎无法解析函数的正确签名-尽管肯定只有一个可能的签名(从返回

  • 大家好,我正在尝试实现一个自定义TextView与字体。我决定使用RobotoTextView。我在资产中也有字体文件夹。我在时出错。 错误:

  • 问题内容: 我上课了。我怎么能说我想成为某个班级的实施者?编写根本无法编译。 问题答案: 使用代替。

  • 我对react、react hooks和js/ts非常陌生。 目前,我正在编码一个简单的按钮,它通过useContext获取一个状态,并通过useReucer和调度函数更新该状态。 我试图将我所有的代码分离到特定的文件中。来自减速器的调度函数在提供程序中作为值传递。 当我在使用者组件中调用传递的函数时,我可以给它一个任何类型的值(在我的示例中是数字)给调度器。我在上下文、reducer等中设置了所