提取返回未知的联合的内部通用类型
Extracting inner generic type of union returning unknown
我正在尝试提取联合的通用类型,但我不知道。
但是,如果我明确尝试提取(检查下面的代码),它 returns 类型正确。为什么?我如何提取通用类型?
'use strict';
type error = {
tag: 'error',
error: string
}
type success<T> = {
tag: 'success',
value: T
}
type Either<T> = error | success<T>;
type extractGeneric<Type> = Type extends Either<infer X> ? X : never
type innerType = extractGeneric<Either<number>>; // type is unknown
type innerType2 = Either<number> extends Either<infer X> ? X : never; // type is number
这是因为 innerType
是 distributive conditional type 而 innerType2
不是。
这意味着他们的行为不同。
引自 distributive conditional types
文档:
If we plug a union type into ToArray, then the conditional type will be applied to each member of that union.
ToArray
等同于 extractGeneric
因此,extractGeneric
首先尝试从 error
获取通用参数,然后从 success
获取。因为 error
没有通用参数它 returns unknown
。这是设计使然
考虑这个伪代码:
type extractGeneric<Type> = Type extends error (unknown) | Type extends success<infer X> ? X | unknown : never
事实上我们最终得到 X | unknown
。因为 unknown
不如 X
联合 X | unknown
returns unknown
.
How can I extract the type generically?
只需使用需要泛型参数的 union 的一部分
type error = {
tag: 'error',
error: string
}
type success<T> = {
tag: 'success',
value: T
}
type Either<T> = error | success<T>;
type extractGeneric<Type> = Type extends success<infer X> ? X : never
type innerType = extractGeneric<Either<number>>; // number
您可能已经注意到它不会抛出错误,因为 Either
扩展了 success
或
您可以关闭分发功能:
type error = {
tag: 'error',
error: string
}
type success<T> = {
tag: 'success',
value: T
}
type Either<T> = error | success<T>;
type extractGeneric<Type> = [Type] extends [Either<infer X>] ? X : never
type innerType = extractGeneric<Either<number>>; // number
P.S。按照惯例,所有类型别名都应大写。
// bad
type foo = number
// good
type Foo = number
我正在尝试提取联合的通用类型,但我不知道。 但是,如果我明确尝试提取(检查下面的代码),它 returns 类型正确。为什么?我如何提取通用类型?
'use strict';
type error = {
tag: 'error',
error: string
}
type success<T> = {
tag: 'success',
value: T
}
type Either<T> = error | success<T>;
type extractGeneric<Type> = Type extends Either<infer X> ? X : never
type innerType = extractGeneric<Either<number>>; // type is unknown
type innerType2 = Either<number> extends Either<infer X> ? X : never; // type is number
这是因为 innerType
是 distributive conditional type 而 innerType2
不是。
这意味着他们的行为不同。
引自 distributive conditional types
文档:
If we plug a union type into ToArray, then the conditional type will be applied to each member of that union.
ToArray
等同于 extractGeneric
因此,extractGeneric
首先尝试从 error
获取通用参数,然后从 success
获取。因为 error
没有通用参数它 returns unknown
。这是设计使然
考虑这个伪代码:
type extractGeneric<Type> = Type extends error (unknown) | Type extends success<infer X> ? X | unknown : never
事实上我们最终得到 X | unknown
。因为 unknown
不如 X
联合 X | unknown
returns unknown
.
How can I extract the type generically?
只需使用需要泛型参数的 union 的一部分
type error = {
tag: 'error',
error: string
}
type success<T> = {
tag: 'success',
value: T
}
type Either<T> = error | success<T>;
type extractGeneric<Type> = Type extends success<infer X> ? X : never
type innerType = extractGeneric<Either<number>>; // number
您可能已经注意到它不会抛出错误,因为 Either
扩展了 success
或
您可以关闭分发功能:
type error = {
tag: 'error',
error: string
}
type success<T> = {
tag: 'success',
value: T
}
type Either<T> = error | success<T>;
type extractGeneric<Type> = [Type] extends [Either<infer X>] ? X : never
type innerType = extractGeneric<Either<number>>; // number
P.S。按照惯例,所有类型别名都应大写。
// bad
type foo = number
// good
type Foo = number