如何在 TypeScript 中将数组类型隐式转换为元组类型?

5

现在,args 是元组类型的可变参数。如何使该构造函数也接受数组,并将其转换为元组类型,生成与构造函数中指定的类型相同的类型?

是否可以在构造时不进行手动断言,即:

const args = [3, 5];

let vector = new Vector(...args as [number, number]);

或者

const args: [number, number] = [3, 5];

let vector = new Vector(...args);

class Vector {
    x: number;
    y: number;

    constructor(...args: [] | [number] | [number, number]) {
        switch(args.length) {
            case 0:
                this.x = 0;
                this.y = 0;
                break;
            case 1:
                this.x = this.y = args[0];
                break;
            case 2:
                this.x = args[0];
                this.y = args[1];
                break;
        }
    }
}

const args = [3, 5];

let vector = new Vector(...args);

编辑:鉴于@philipp-fritsche的回答,如果我添加这些重载呢?

Playground

class Vector {
    x: number;
    y: number;

    constructor();
    constructor(xy: number);
    constructor(x: number, y: number);
    constructor(arg1?: number, arg2?: number) {
        if(arg1 === undefined) {
            this.x = this.y = 0;
        } else if (arg2 == undefined) {
            this.x = this.y = arg1;
        } else {
            this.x = arg1;
            this.y = arg2;
        }
    }
}

const args = [1, 2];

let vector = new Vector(...args);

听起来你想要 const args = [3, 5] as const; - kaya3
@kaya3 有没有一种方法可以不在 Vector 类之外执行任何操作? - Murolem
嗯,args 的类型是 number[],所以要编辑 Vector 类以进行此类型检查的唯一方法是让您的构造函数接受 number[] - kaya3
1
在这里,您可以找到重载 https://www.typescriptlang.org/play?#code/MYGwhgzhAEBqCmwAuB7ATtA3gKGn6AHgFzQB2ArgLYBG8aA3LvgJ4kU12NN7AqkRI05ZOgAUASkb5ovfoOGo0oggH42VWmkncZfAUJFLV6jmgA00ZmrIa62nbP0KxYNAHMAjNfaaLrtwBM3rZaWDrSAJYAZtCi-h7QALzJ0OSkACbwURGk8OniYdJF+EgAFhEQAHQESdBlFZXMtQAMUsXQAL7Q8CAQ8NDRsf4BSYmpGVk5eQU47UX1VTVjC4218W3FXT19hXMl5Ytr7h4beytNY8On0h06t7fYjkjQ-jBjANoeFgEAulwg8GeADdEIparkAO5wUFiSpw16SIA - captain-yossarian from Ukraine
2个回答

5
这里定义每个REST参数并没有任何好处。
class Vector {
    x: number;
    y: number;

    constructor(x?: number, y?: number) {
        this.x = x ?? 0
        this.y = y ?? x ?? 0
    }
}

const args = [3, 5];

let vector = new Vector(...args);

这个方法的原理是因为参数类型推断为number[]。而number[]中的元素01number | undefined,与Vector的参数匹配。
如果你指定了...args: [] | [number] | [number, number],则允许使用012个参数。但是number[]可以有>=0的元素,因此这违反了你明确规定的类型要求。

0
考虑到@philipp-fritsche的回答和@captain-yossarian的评论,这是最终版本,并进行了小的添加。
class Vector {
    x: number;
    y: number;

    constructor();
    constructor(xy?: number);
    constructor(x?: number, y?: number);
    constructor(xy?: Vector);

    constructor(arg1?: number | Vector, arg2?: number) {
        if (arg1 === undefined) {
            this.x = this.y = 0;
        } else if (arg1 instanceof Vector) {
            this.x = arg1.x;
            this.y = arg1.y;
        } else if (arg2 == undefined) {
            this.x = this.y = arg1;
        } else {
            this.x = arg1;
            this.y = arg2;
        }
    }
}

const args = [1, 2];

let vector = new Vector(...args);

console.log(vector);

游乐场


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接