使用 infer 关键字创建反向类型查找? [复制]
Posted
技术标签:
【中文标题】使用 infer 关键字创建反向类型查找? [复制]【英文标题】:Create a reverse type look up using the infer keyword? [duplicate] 【发布时间】:2021-10-25 05:23:24 【问题描述】:这就是我所拥有的,我有各种类型,并且我有该类型的字符串表示:
type PossibleValueTypes = Color | number | Position;
type PossibleValueTypesAsString = "color" | "number" | "position";
type ValueTypeMap =
"color" : Color;
"number" : number;
"position" : Position;
;
现在,给出一个给定的字符串表示,返回值类型很容易,例如;
function generateRandomValueOfType<T extends PossibleValueTypesAsString>(type: T) : ValueTypeMap[T]
if (type === 'color')
return
r: 1,
g: 1,
b: 1,
a: 1,
as ValueTypeMap[T]
if (type === "position")
return
x:1,
y: 1
as ValueTypeMap[T]
if (type === "number")
return 1 as ValueTypeMap[T];
throw new Error ("We shouldn't have got here");
;
const a: Position = generateRandomValueOfType("position");
const b: number = generateRandomValueOfType("position"); // Expected error!
现在的问题是 - 如果我想做相反的事情,那就是 - 给定一个值类型,确定字符串表示。
我能做的最好的就是做一个像这样的链式条件:
type ReverseValueTypeLookup<T extends PossibleValueTypes> = T extends Color ? "color" : T extends number ? "number" : T extends Position ? "position": never;
function hasAValueAcceptingCallback<T extends PossibleValueTypes> (callback: (value: T) => void, valueTypeAsString: ReverseValueTypeLookup<T>)
const value = generateRandomValueOfType(valueTypeAsString);
//Argument of type 'ValueTypeMap[ReverseValueTypeLookup<T>]' is not assignable to parameter of type 'T'.
//'ValueTypeMap[ReverseValueTypeLookup<T>]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PossibleValueTypes'.
callback(value);
但这在我给出的示例中实际上不起作用。
有没有更简洁的方法来实现我在这里尝试做的这两件事?
TS Playground
【问题讨论】:
如果我在这里将answer 翻译成另一个问题,我会得到this,但请注意,在这个答案和你接受的答案中,如果没有类型断言,你就不能调用callback(value)
;编译器只是不够聪明,无法看到这将是安全的。但是您提出的问题似乎是“进行反向类型查找”而不是“当T
是一些未指定的泛型时,让编译器相信Fwd<Rev<T>>
等同于T
”,所以我不会担心关于那个。
【参考方案1】:
一个相当冗长但可行的解决方案是......
type ReverseValueTypeLookup<T extends ValueTypeMap[keyof ValueTypeMap]> =
[x in keyof ValueTypeMap]: ValueTypeMap[x] extends T ? x : never;
[keyof ValueTypeMap];
// exclude key x when ValueTypeMap[x] is not assignable to T, and then get the types of values
type C = ReverseValueTypeLookup<Color>; // type 'color'
type N = ReverseValueTypeLookup<number>; // type 'number'
如果您仍然无法区分Color | number | Position
中的类型,请使用类型缩小,如...
var data: Color | number | Position;
if (typeof data === 'number')
// data is number
else if ('r' in data)
// data is Color
else if ('x' in data)
// data is Position
【讨论】:
以上是关于使用 infer 关键字创建反向类型查找? [复制]的主要内容,如果未能解决你的问题,请参考以下文章