有办法吗?我知道,可以/不可以或切换“类型”属性以获取特定的接口。但是我可以用函数(或方法)的返回值做类似的事情吗?
interface test1 {
type: 'test1'
}
interface test2 {
type: 'test2'
}
type unType = test1 | test2;
//i know property "type"'s value
//can i somehow use this information to infer specific type (test1 or test2)
function whichType<T>(typeValue): T {
return null;
}
const tt1 = whichType<unType>('test1');// should be interface test1
const tt2 = whichType<unType>('test2');// should be interface test2
答案 0 :(得分:3)
您可以按照TJ Crowder的建议使用重载,如果您只有几个接口,这可能是最好的解决方案,因为编写理解很容易。
更通用的解决方案是使用Extract
条件类型根据传入的字符串提取类型:
interface test1 { type: 'test1' }
interface test2 { type: 'test2' }
type unType = test1 | test2;
function whichType<K extends unType['type']>(typeValue: K): Extract<unType, {type: K}> {
return null!;
}
const tt1 = whichType('test1'); // test1
const tt2 = whichType('test2'); // test2
可以构建一个适用于任何联合的解决方案,但由于typescript不支持部分类型参数推断,因此它要求您使用函数currying:
function whichType<T extends { type: string}>() {
return function <K extends T['type']>(typeValue: K): Extract<T, {type: K}> {
return null!;
}
}
const tt1 = whichType<unType>()('test1'); // test1
const tt2 = whichType<unType>()('test2'); // test2
答案 1 :(得分:2)
如果通过使用函数重载调用whichType
时确实使用文字,则可以从类型角度进行操作:
interface test1 {
type: 'test1'
}
interface test2 {
type: 'test2'
}
type unType = test1 | test2;
function whichType(typeValue: 'test1'): test1;
function whichType(typeValue: 'test2'): test2;
function whichType(typeValue: string): unType {
switch (typeValue) {
case 'test1':
return <test1>null;
case 'test2':
return <test2>null;
default:
throw new Error(`Unknown type ${typeValue}`);
}
}
const tt1 = whichType('test1'); // tt1's type is test1
const tt2 = whichType('test2'); // tt2's type is test2
从代码注释中可以看到,您仍然需要运行时逻辑来在运行时进行处理。
要允许在对whichType
的调用中使用非文字字符串,您需要添加另一个重载:
function whichType(typeValue: string): unType;
...然后处理您不知道类型的事实。 :-|
[在操场上] [2]
[2]:函数whichType(typeValue:string):unType;