让我们从一些定义开始:
type Contravariant<T> = (t: T) => void;
declare let cNum: Contravariant<number>;
declare let cStr: Contravariant<string>;现在,假设我想要创建一个函数,可以在一个Contravariant联合类型的数组中传递它。首先,我使用了一个简单的方法:
declare function f1<T>(a: T[]): void;
f1([cNum, cStr]); // T inferred as 'Contravariant<number> | Contravariant<string>'看起来不错!但是,数组目前可以采用任何类型,我想将其限制为Contravariant类型,因此让T扩展Contravariant。
declare function f2<T extends Contravariant<any>>(a: T[]): void;
f2([cNum, cStr]); // T inferred as 'Contravariant<number> | Contravariant<string>'似乎效果不错。然而,eslint现在抱怨使用any。unknown显然不起作用,因为它是反变体。
在这种情况下使用any有哪些潜在的缺点?我能安全地使用any吗?在不使用any的情况下,有什么方法可以做到吗?
我尝试过的其他一些事情:
declare function f3<T extends Contravariant<U>, U>(a: T[]): void;
f3([cNum, cStr]);
// Type 'Contravariant<number>' is not assignable to type 'Contravariant<unknown>'.
// Type 'unknown' is not assignable to type 'number'.declare function f3a<U>(a: Contravariant<U>[]): void;
f3a([cNum, cStr]);
// Type 'Contravariant<string>' is not assignable to type 'Contravariant<number>'.
// Type 'number' is not assignable to type 'string'.declare function f4<T extends Contravariant<T extends Contravariant<infer I> ? I : never>>(a: T[]): void;
f4([cNum, cStr]);
// Type 'Contravariant<string>' is not assignable to type 'Contravariant<string | number>'.
// Type 'string | number' is not assignable to type 'string'.
// Type 'number' is not assignable to type 'string'.为什么所有这些(f3,f3a,f4)都会导致不同类型的推断?他们看起来都对我做了同样的事。
发布于 2022-07-17 17:31:50
我看不出在这里使用any有什么坏处。毕竟,它只是用于约束。但是,如果您确实需要一个没有any的解决方案,您可能会对以下内容感兴趣:
declare function f1<
T extends unknown[]
>(a: [...{ [K in keyof T]: Contravariant<T[K]> }]): void;
f1([cNum, cStr]);在本例中,T将被推断为[number, string]。
https://stackoverflow.com/questions/73013460
复制相似问题