Typescript 基于输入结构的推断类型

Typescript 基于输入结构的推断类型,typescript,typescript-generics,Typescript,Typescript Generics,我正在努力根据输入参数推断类型。基本上,我想使用对象的结构来推断返回类型(虽然不只是返回类型)。我认为诀窍是使用,但我无法让它工作: type Active = { name: string; active: true }; type Inactive = { name: string; active: false }; type IdWithAct = Active | Inactive; export const getIdWithType = < Arg extends IdW

我正在努力根据输入参数推断类型。基本上,我想使用对象的结构来推断返回类型(虽然不只是返回类型)。我认为诀窍是使用,但我无法让它工作:

type Active = { name: string; active: true };
type Inactive = { name: string; active: false };
type IdWithAct = Active | Inactive;

export const getIdWithType = <
  Arg extends IdWithAct,
  T extends Arg extends Active ? 'ActiveItem' : 'InactiveItem'
>({
  name,
  active,
}: IdWithAct): {name: string, typeName: T } =>  ({
    name,
    typeName: active ? 'ActiveItem' : 'InactiveItem',
  });
看,这个解决方案很有吸引力,因为它相当明确地表达了重载的意图

运行时断言 运行时断言的建议是可行的,但我认为它有点太神奇了,如果返回对象的差异超过一个值,那么它很可能会变得相当混乱:

type IdWithAct<T> = { name: string; active: T };
type Status<T> = T extends true ? 'ActiveItem' : 'InactiveItem'

export const getIdWithType = <T extends boolean>({
    name,
    active,
}: IdWithAct<T>) => ({
    name,
    typeName: (active ? 'ActiveItem' : 'InactiveItem') as Status<T>,
});

const foo = getIdWithType({ name: 'x', active: true }) // { name: string; typeName: "ActiveItem"; }
const bar = getIdWithType({ name: 'x', active: false }) // { name: string; typeName: "InactiveItem"; }

const test = (active: boolean) => getIdWithType({ name: 'x', active })
类型IdWithAct={name:string;active:T};
type Status=T扩展为true?'ActiveItem':'InactiveItem'
导出常量getIdWithType=({
名称
活跃的,
}:IdWithAct)=>({
名称
typeName:(活动?'ActiveItem':'InactiveItem')作为状态,
});
const foo=getIdWithType({name:'x',active:true})/{name:string;typeName:'ActiveItem;}
const bar=getIdWithType({name:'x',active:false})/{name:string;typeName:“InactiveItem”;}
常量测试=(活动:布尔)=>getIdWithType({name:'x',active})

您需要再添加一个重载:


键入ActivityWithName={name:string,active:T}
键入IdWithAct=ActivityWithName
类型类型='ActiveItem'|'InactiveItem'
type Ret={name:string,typeName:T}//使用泛型参数
函数getFragnAmeAndFromActive(args:ActivityWithName):Ret
函数getFragnAmeAndFromActive(args:ActivityWithName):Ret
函数getFragNameAndIdFromActive(args:ActivityWithName):Ret//less-specific重载
函数getFragnAmeAndFromActive({
名称
活跃的,
}:IdWithAct):Ret{
返回{
名称
typeName:活动?'ActiveItem':'InactiveItem',
}
}
const retActive=getFragNameAndIdFromActive({name:'activeItem',active:true})
const retInactive=getFragnAmeAndFromActive({name:'activeItem',active:false})
功能测试(活动:布尔值){
const ret=getFragNameAndIdFromActive({name:'activeItem',active})//确定
}

仅使用类型断言,因为泛型只能在调用函数时解析,而不能在函数中尝试写入overloads@captain-yossarian-重载看起来很吸引人,但我无法让它们正常工作,请参阅我对该问题的更新。您可能会面临此问题-W.R>t以上评论您可以检查此问题-
type IdWithAct<T> = { name: string; active: T };
type Status<T> = T extends true ? 'ActiveItem' : 'InactiveItem'

export const getIdWithType = <T extends boolean>({
    name,
    active,
}: IdWithAct<T>) => ({
    name,
    typeName: (active ? 'ActiveItem' : 'InactiveItem') as Status<T>,
});

const foo = getIdWithType({ name: 'x', active: true }) // { name: string; typeName: "ActiveItem"; }
const bar = getIdWithType({ name: 'x', active: false }) // { name: string; typeName: "InactiveItem"; }

const test = (active: boolean) => getIdWithType({ name: 'x', active })