在 TypeScript 中定义没有不兼容错误的本地类型
Defining Local Types Without Incompatibility Errors in TypeScript
TypeScript 版本:3.8.2
搜索词: map, over, utility, type, result, keys, extract
代码
以下帮手为我工作得很好:
export type ComputeUnionValue<V extends AnyCodec[]> = {
[i in Extract<keyof V, number>]: GetValue<V[i]>;
}[Extract<keyof V, number>];
我尝试简化这个助手,它在两个地方使用了 Extract<keyof V, number>
。
export type ComputeUnionValue<V extends AnyCodec[], E = Extract<keyof V, number>> = {
[i in E]: GetValue<V[i]>;
}[E];
E
个 [i in E]
个错误:
Type 'E' is not assignable to type 'string | number | symbol'.
Type 'E' is not assignable to type 'symbol'.ts(2322)
V[i]
错误:
Type 'V[i]' does not satisfy the constraint 'AnyCodec'.
Type 'V[E]' is not assignable to type 'Codec<VType, unknown>'.
Type 'AnyCodec[][E]' is not assignable to type 'Codec<VType, unknown>'.ts(2344)
和
Type 'i' cannot be used to index type 'V'
我使用 E =
是为了在范围内使用该新类型...而不是作为可选参数。但它是一个可选参数的事实似乎影响了 "guarantees" 可以这么说,这导致了上面的不兼容性。有没有一种方法可以创建 E
类型——该实用程序类型的本地类型——以一种没有潜在类型不兼容的方式?
虽然我看到类型参数用作 'local types variable',但我认为这不是一个好主意,因为它们基本上将内部逻辑暴露给外部(毕竟有人可以传入 E
而不是使用默认值)。它们还意味着用户必须知道哪些参数是 "real",哪些只是 "local",在我看来这是糟糕的 DX。 (仅供参考:GH 上有一个允许本地类型别名的提案,但我认为它没有任何进展)
也就是说,您收到错误的原因是 =
只是为类型参数提供了默认值,但类型参数可以是任何类型,包括不能使用的类型在映射类型中。
解决方案很简单,如果有点冗长,请为类型参数提供默认值和约束(使用extends
):
export type ComputeUnionValue<V extends AnyCodec[], E extends Extract<keyof V, number> = Extract<keyof V, number>> = {
[i in E]: GetValue<V[i]>;
}[E];
TypeScript 版本:3.8.2
搜索词: map, over, utility, type, result, keys, extract
代码
以下帮手为我工作得很好:
export type ComputeUnionValue<V extends AnyCodec[]> = {
[i in Extract<keyof V, number>]: GetValue<V[i]>;
}[Extract<keyof V, number>];
我尝试简化这个助手,它在两个地方使用了 Extract<keyof V, number>
。
export type ComputeUnionValue<V extends AnyCodec[], E = Extract<keyof V, number>> = {
[i in E]: GetValue<V[i]>;
}[E];
E
个 [i in E]
个错误:
Type 'E' is not assignable to type 'string | number | symbol'.
Type 'E' is not assignable to type 'symbol'.ts(2322)
V[i]
错误:
Type 'V[i]' does not satisfy the constraint 'AnyCodec'.
Type 'V[E]' is not assignable to type 'Codec<VType, unknown>'.
Type 'AnyCodec[][E]' is not assignable to type 'Codec<VType, unknown>'.ts(2344)
和
Type 'i' cannot be used to index type 'V'
我使用 E =
是为了在范围内使用该新类型...而不是作为可选参数。但它是一个可选参数的事实似乎影响了 "guarantees" 可以这么说,这导致了上面的不兼容性。有没有一种方法可以创建 E
类型——该实用程序类型的本地类型——以一种没有潜在类型不兼容的方式?
虽然我看到类型参数用作 'local types variable',但我认为这不是一个好主意,因为它们基本上将内部逻辑暴露给外部(毕竟有人可以传入 E
而不是使用默认值)。它们还意味着用户必须知道哪些参数是 "real",哪些只是 "local",在我看来这是糟糕的 DX。 (仅供参考:GH 上有一个允许本地类型别名的提案,但我认为它没有任何进展)
也就是说,您收到错误的原因是 =
只是为类型参数提供了默认值,但类型参数可以是任何类型,包括不能使用的类型在映射类型中。
解决方案很简单,如果有点冗长,请为类型参数提供默认值和约束(使用extends
):
export type ComputeUnionValue<V extends AnyCodec[], E extends Extract<keyof V, number> = Extract<keyof V, number>> = {
[i in E]: GetValue<V[i]>;
}[E];