如何解决处理未包装的可变元组类型
考虑以下代码:
interface Wrap<Value> {
pick(): Value
}
class WrapConstant<Value> implements Wrap<Value> {
constructor(public readonly a: Value) { }
pick(): Value { return this.a }
}
type Unwrap<Wrapped> = { [P in keyof Wrapped]: Wrapped[P] extends Wrap<infer Value> ? Value : never }
class WrapTuple<Tuple extends Wrap<unknown>[],Value = Unwrap<Tuple>> implements Wrap<Value> {
readonly ts: Tuple
constructor(...t: Tuple) { this.ts = t }
pick(): Value { return this.ts.map(a => a.pick()) } // fails to type check
}
type T1 = Unwrap<[WrapConstant<number>,WrapConstant<string>]> // [number,string]
new WrapTuple(new WrapConstant(1),new WrapConstant("hello")).pick() // [1,"hello"]
基本上,我正在解开一个我知道遵循某种形状的元组(Wrap<Values>
的元组)。 pick()
中的 WrapTuple
函数应该保证返回相同形状的未包装类型(由 Unwrap<Tuple>
提供),尽管我在该行中收到类型检查错误。问题:
- 这是不是因为条件类型推断不能保证
Unwrap<Tuple>
具有相同的形状? - 是否可以在不强制转换
as unknown as Value
的情况下使其工作?
更新: 正如 Linda 所评论的,映射元组不会产生元组。我尝试按照建议合并我自己的地图声明here:
interface Array<T> {
map<U>(callbackfn: (value: T,index: number,array: T[]) => U,thisArg?: any): { [K in keyof this]: U }
}
但这仍然需要将 map
断言为 Value
:
pick(): Value { return this.ts.map(a => a.pick()) as Value }
解决方法
更新
解决方法如下:
interface Wrap<Value> {
pick(): Value
}
class WrapConstant<Value> implements Wrap<Value> {
constructor(public readonly a: Value) { }
pick(): Value { return this.a }
}
type Unwrap<Wrapped> = { [P in keyof Wrapped]: Wrapped[P] extends Wrap<infer Value> ? Value : never }
class WrapTuple<Tuple extends ReadonlyArray<Wrap<unknown>>> implements Wrap<unknown> {
readonly ts: Tuple
constructor(...ts: [...Tuple]) {
this.ts = ts
}
pick(): Unwrap<[...Tuple]> // <-- added overload
pick() {
return this.ts.map(a => a.pick())
}
}
const foo = new WrapTuple(new WrapConstant(1),new WrapConstant("hello")).pick() // [number,string]
看起来它在方法重载的情况下按预期工作
Here 您可以找到更多元组的解决方法。这是我的博客
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。