Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 泛型对象返回类型是方法链接的结果_Typescript_Typescript Generics - Fatal编程技术网

Typescript 泛型对象返回类型是方法链接的结果

Typescript 泛型对象返回类型是方法链接的结果,typescript,typescript-generics,Typescript,Typescript Generics,我想做以下工作: var result=loader .add(1) .add(“你好”) .add(true) .run(); 我想构造这个理论上的加载器对象,使结果类型为[number,string,boolean],而无需手动声明。有没有办法在TypeScript中做到这一点?更新:TypeScript 4.0将提供更灵活的内置元组操作功能推送将简单地实现为[…T,V]。因此,整个实现转化为以下相对简单的代码: type Loader<T extends any[]> = {

我想做以下工作:

var result=loader
.add(1)
.add(“你好”)
.add(true)
.run();

我想构造这个理论上的
加载器
对象,使结果类型为
[number,string,boolean]
,而无需手动声明。有没有办法在TypeScript中做到这一点?

更新:TypeScript 4.0将提供更灵活的内置元组操作功能<代码>推送将简单地实现为
[…T,V]
。因此,整个实现转化为以下相对简单的代码:

type Loader<T extends any[]> = {
    add<V>(x: V): Loader<[...T, V]>;
    run(): T
}
declare const loader: Loader<[]>;

var result = loader.add(1).add("hello").add(true).run(); //[number, string, boolean]
给定
Cons
Tail
Push
的自然表示如下:

除了
PushX
之外的每一行看起来都像是递归定义,我们故意在
PushX
处切断,放弃并忘记元素的顺序(
PushX
Array

现在我们可以这样做:

type Test = Push<[1, 2, 3, 4, 5, 6, 7, 8], 9> // [1, 2, 3, 4, 5, 6, 7, 8, 9]
让我们试试看:

var result = loader.add(1).add("hello").add(true).run(); //[number, string, boolean]
看起来不错。希望有帮助;祝你好运


更新 以上仅适用于启用了
--strictFunctionTypes
的情况。如果必须不使用该编译器标志,则可以使用以下定义的
Push

type PushTuple = [[0], [0, 0], [0, 0, 0],
    [0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
type Push<
    T extends any[],
    V,
    L = PushTuple[T['length']],
    P = { [K in keyof L]: K extends keyof T ? T[K] : V }
    > = P extends any[] ? P : never;
type PushTuple=[[0]、[0,0]、[0,0,0],
[0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
类型推送<
T扩展任何[],
v
L=PushTuple[T['length']],
P={[K在keyof L]:K扩展了keyof T?T[K]:V}
>=P扩展任何[]?P:从来没有;
对于较小的受支持元组大小,它更简洁,这很好,但是重复是受支持元组数量的二次增长(O(n2)增长),而不是线性增长(O(n)增长),这不太好。无论如何,它使用TS3.1中介绍的方法工作

这取决于你


祝你好运

这是一个很棒的解决方案。我完全可以选择一个合理的最大值。但是,我尝试完全按照您提供的方式使用您的示例,从结果推断出的类型是
[number,…undefined[]]
。你的例子可能不太正确吗?如果可以的话,我正在使用typescript 3.1.6打开
--strict
(或者至少
--strictFunctionTypes
,这似乎是原因所在)。我确信我可以做一些改变,让
Push
在没有它的情况下工作,但是
--strict
非常有用,所以我尽量少花时间关闭它。更新了
Push
的版本,该版本可以在没有
--strict
的情况下工作
type Test = Push<[1, 2, 3, 4, 5, 6, 7, 8], 9> // [1, 2, 3, 4, 5, 6, 7, 8, 9]
type Loader<T extends any[]> = {
  add<V>(x: V): Loader<Push<T, V>>;
  run(): T
}
declare const loader: Loader<[]>;
var result = loader.add(1).add("hello").add(true).run(); //[number, string, boolean]
type PushTuple = [[0], [0, 0], [0, 0, 0],
    [0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
type Push<
    T extends any[],
    V,
    L = PushTuple[T['length']],
    P = { [K in keyof L]: K extends keyof T ? T[K] : V }
    > = P extends any[] ? P : never;