TypeScript中动态,无限,编号变量名称的类型定义

如何解决TypeScript中动态,无限,编号变量名称的类型定义

我正在为没有类型定义的jQuery库编写类型定义文件index.d.ts)。

某些方法需要一个对象作为参数,该对象具有所有可用属性集的子集。除了显式定义的变量外,该库还提供了使用无限数量的编号变量的功能(本质上是一个数组的实现,没有实际数组的好处)。

export interface SomeLibOption {
    a?: number,b?: string,c?: boolean,// so far so good,Now the problematic part:
    x?: number,x2?: number,x3?: number,x4?: number,x5?: number,// ...
    x1000?: number,// ...
    x500000?: number,// ...
}

declare global {
    interface JQuery<TElement = HTMLElement> {
        setFoo(foo: SomeLibOption): this;
        setBar(bar: SomeLibOption): this;
    }
}

用法如下:

$('someSelector').setBar({
    a: 2,x: 3,x1: 9,x2: 5,x3: 4,// ...
    x1000: 42,// ...
});

对所有可能的变量名进行硬编码似乎是不可行的。毕竟它们是无限的。

如何在类型定义文件中定义它们?甚至有可能吗?

澄清

我正在寻找一种解决方案,将'x' + number定义为有效属性,但将'y' + number定义为有效属性,同时保留诸如a?: number,c?: boolean之类的现有定义。

基本上,属性应与正则表达式/^x[0-9]+$/相匹配。

解决方法

TypeScript 4.1将像Column name Data type Constraints DEPARTMENT_ID NUMBER(5) PK DEPARTMENT_NAME VARCHAR2(25) NOT NULL LOCATION_ID VARCHAR2(15) Sample Output: Department Details are : 1000,ADMIN,HQ-101 1010,DEVELOPMENT,CBE-103 1020,TESTING,CHN-102 一样支持template literal types来表示字符串连接。它还将支持recursive conditional types

您将无法将set serveroutput on; declare v_dno department.department_id%type; v_dname department.department_name%type; v_loc department.location_id%type; begin dbms_output.put_line('Department Details are :'); loop dbms_output.put_line(v_dno || ',' || v_dname || ',' || v_loc); end loop; commit; end; / 形式的无限属性表示为TypeScript中的具体类型,至少据我所知。根据{{​​3}}的规定,对模板文字类型(如`${A}${B}`的支持如下:

"x"+number

,但是它并没有按照您在此处需要的方式扩展到键类型:

`x${number}`

否则,您将只能将type XNumber = `x${"" | number}`; let xNumber: XNumber; xNumber = "x12345"; // okay xNumber = "xNope"; // error! xNumber = "y"; // error! xNumber = "x-3.14159"; // okay I guess 表示为microsoft/TypeScript#40598而不是特定类型。

模板字面量操作目前很棘手,因为存在两个主要陷阱:联合类型爆炸和递归限制。从概念上讲,您可以提出一种const foo: Partial<Record<XNumber,number>> = {}; foo.x = 1; foo.x12345 = 2; // error! ? 之类的SomeLibOption类型,然后说您将接受Digit类型的键,然后是0|1|2|3|4|5|6|7|8|9。但这是一个巨大的结合,它破坏了编译器。因此,相反,您可以将其表示为诸如"x"之类的递归类型检查,但由于递归限制,该类型最终会在长字符串如`${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}`上轰炸。

以下示例尝试通过使用type IsDigits<T extends string> = T extends "" ? "yes" : `${Digit}${infer U}` ? IsDigits<U> : "no"进行100个元素的适度合并,并对两个数字或一个数字的组进行递归来在它们之间走线:

IsDigits<"13263548274827">

一团糟,但这是您的${Digit}${Digit}方法:

interface BaseLibOption {
    a?: number,b?: string,c?: boolean,}

type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type IsAllDigits<T extends string,Y = T,N = never> = string extends T ? N :
    T extends "" ? Y : T extends `${Digit}${Digit}${infer U}` ? IsAllDigits<U,Y,N> :
    T extends `${Digit}${infer U}` ? IsAllDigits<U,N> : N
type SomeLibOption<T> = { [K in keyof T]?: K extends keyof BaseLibOption ? BaseLibOption[K] :
    K extends `x${infer N}` ? IsAllDigits<N,number> : never }

让我们看看它是否有效:

JQuery

我认为不错。

generic constraint

,

使用此符号,您可以定义一个接口,该接口将具有任意数量的属性,其键始终为字符串,值始终为数字

interface MyInterface {
  [key: string]: number
}

下面是一个使用与您的问题相同的接口名称的示例,并简单演示了如何在函数定义和调用中使用它。

// Define an interface with an arbitrary of key value pairs in which
// keys are always strings and values are always numbers
interface SomeLibOption {
  [key: string]: number
}

// Example function with a parameter of type
// SomeLibOption defined above
function setBar(op: SomeLibOption) {
  // Do something...
  // For example,the following line prints out sum of op.a and op.b
  console.log(`a + b = ${op.a + op.b}`)
}

// Example function call passing in a SomeLibOption
// object that has arbitrary key value pairs
setBar({
  a: 1,b: 2,c: 3,a2: 400,b2: 500
})

请注意,每个语句后的分号;都被省略了,因为我们假设我们使用的是TypeScript版本。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?