通用类型的打字稿长度

时间:2019-05-08 05:42:40

标签: javascript typescript generics

我有一个类似的功能

export function is<T extends any[]>(...klasses): Predictor<T> {
    return (...variables: T) => {
        return variables
            .every((variable, index) => variable instanceof klasses[index]);
    }
}

在此示例中,我想确保klassesT的数组具有相同的长度。如何使klasses类型的any[]T具有相同的长度?

更新

根据评论,我已将其更新为

export function is<T extends Array<any>>(...klasses: any[] & {length: T['length']}): Predictor<T> {
    return (...variables: T) => {
        return variables
            .every((variable, index) => variable instanceof klasses[index]);
    }
}

2 个答案:

答案 0 :(得分:2)

这是另一个解决方案,它使用第二个类型的参数作为长度。我看到您不希望使用其他类型参数,但是出于完整性考虑,我还是会添加它。

export function is<L extends number, T extends any[] & {length: L}>(...klasses: any[] & {length: L}) {
    return (...variables: T) => {
        return variables
            .every((variable, index) => variable instanceof klasses[index]);
    }
}

is(Number, String)(1, 1); // ok
is(Number, String)(1); // error

答案 1 :(得分:1)

您可以查询classes数组的长度,然后将变量的长度限制为相同:

export function is<TClasses extends any[]>(...klasses: TClasses) {
    return (...variables: any[] & { length: TClasses['length'] }) => {
        return variables
            .every((variable, index) => variable instanceof klasses[index]);
    }
}

is(Number, String)(1, 1); // ok
is(Number, String)(1); // error: Types of property 'length' are incompatible

但是在这种情况下,您将无法预先指定变量类型。如果可以更改实现以允许自动推断类类型,则可以使用:

export function is<T extends any[]>() {
    return <TClasses extends any[]>(...klasses: TClasses) =>
        (...variables: T & { length: TClasses['length'] }) =>
            variables.every((variable, index) => variable instanceof klasses[index]);
}

is<string[]>()(Number, String)('1', '1'); // ok
is<string[]>()(Number, String)(1, 1); // error: not assignable to type 'string[]'
is()(Number, String)(1); // error: Types of property 'length' are incompatible