我正在寻找一种具有可以返回多种类型并且将返回值分配给联合中的一种类型的功能的函数的方法。
interface Alpha {}
interface Beta {}
interface Gamma {}
const hello = (arg): Alpha | Beta | Gamma => {
if (arg === 'Alpha') return {} as Alpha;
if (arg === 'Beta') return {} as Beta;
if (arg === 'Gamma') return {} as Gamma;
throw new Error('meow');
};
const x = hello('Beta');
当前x
可以是Alpha | Beta | Gamma
,但是运行时知道它是Beta
。 x
是否可能知道其类型为Beta
?
更新
下面是一个带有日期的Recipe
接口和可为空的示例,以及一个RecipeQuery
允许您查询不可为空的结果的示例。
interface Recipe {
date: Date | null
}
interface RecipeQuery {
date: {
null: boolean
}
}
我正在尝试进行重载,即如果查询为null
false
,则Recipe
中的日期现在将始终为string
,而不是联合
function Query(q: Merge<RecipeQuery, { date: { null: false } }>): Merge<Recipe, { date: Date }>;
这不能正常工作。
基本上我想要的是这个
function query(recipeQuery: RecipeQuery) {
if (recipeQuery.date.null === true) return { date: null } as Recipe;
if (recipeQuery.date.null === false) return { date: new Date } as Merge<Recipe, { date: Date }>;
throw new Error('');
}
答案 0 :(得分:3)
有几种方法可以做到这一点。我最喜欢的一种是使用“映射类型”:
interface HelloMapping {
'Alpha': Alpha
'Beta': Beta
'Gamma': Gamma
}
const hello = <T extends keyof HelloMapping>(arg: T)
: HelloMapping[T] => {
if (arg === 'Alpha') return {} as Alpha;
if (arg === 'Beta') return {} as Beta;
if (arg === 'Gamma') return {} as Gamma;
throw new Error('meow');
};
您也可以通过重载来实现:
function hello(arg: 'Alpha'): Alpha
function hello(arg: 'Beta'): Beta
function hello(arg: 'Gamma'): Gamma
function hello(arg: 'Alpha' | 'Beta' | 'Gamma') {
if (arg === 'Alpha') return {} as Alpha;
if (arg === 'Beta') return {} as Beta;
if (arg === 'Gamma') return {} as Gamma;
throw new Error('meow');
};