我正在使用由 ts-proto 生成的protobuf oneof union 类型,并且我想构建一个可以从联合中提取分支的辅助函数。但是,我无法设计一组类型约束来表示我的助手的返回类型应该等于联合分支中相应属性的类型。我怎样才能使这项工作?
type FirstType = number;
type SecondType = string;
type ThirdType = number[];
type MyUnion =
{ $case: 'first'; first: FirstType }
| { $case: 'second'; second: SecondType }
| { $case: 'third'; third: ThirdType };
type UnionCase = MyUnion['$case'];
// This doesn't work: K can't be used in the computed property
type UnionBranch<K extends UnionCase, T> = T extends {$case: K, [K]: infer Prop} ? Prop : never;
function getByCase<K extends UnionCase, T>(obj: MyUnion, $case: K): T | undefined {
// If I were comparing against a literal, the type would be narrowed within this branch.
if (obj.$case === $case) {
// It can't realize that $case has the same name as the property
return obj[$case];
}
return undefined;
}
const myObj = {
$case: 'first',
first: 5,
} as const;
const res = getByCase(myObj, 'first');
// res should be type: number