typescript返回类型正在扩展为整个枚举

typescript返回类型正在扩展为整个枚举,typescript,Typescript,在下面的代码中,如果我没有在每个操作中使用'as'关键字指定种类,那么推断出的方法类型会将其扩展到任何种类类型。有没有办法避免将“Kind.PAYPAL”重复为Kind.PAYPAL enum Kind { CASH = 'CASH', PAYPAL = 'PAYPAL', CREDIT = 'CREDIT' } const Cash = () => ({ kind: Kind.CASH as Kind.CASH, }); const PayPal =

在下面的代码中,如果我没有在每个操作中使用'as'关键字指定种类,那么推断出的方法类型会将其扩展到任何种类类型。有没有办法避免将“Kind.PAYPAL”重复为Kind.PAYPAL

enum Kind {
    CASH = 'CASH',
    PAYPAL = 'PAYPAL',
    CREDIT = 'CREDIT'
}

const Cash = () => ({
    kind: Kind.CASH as Kind.CASH,
});

const PayPal = (email: string) => ({
    kind: Kind.PAYPAL as Kind.PAYPAL,
    email
});

const CreditCard = (payload: { cardNumber: string, cvv: string }) => ({
    kind: Kind.CREDIT as Kind.CREDIT,
    payload
});

type PaymentMethod = ReturnType<
    typeof Cash
    | typeof PayPal
    | typeof CreditCard
>;

function describePaymentMethod(method: PaymentMethod): string {
  switch (method.kind) {
    case Kind.CASH:
      // Here, method has type Cash
      return "Cash";

    case Kind.PAYPAL:
      // Here, method has type PayPal
      return `PayPal (${method.email})`;

    case Kind.CREDIT:
      // Here, method has type CreditCard
      return `Credit card (${method.payload.cardNumber})`;
  }
}
枚举类型{
现金=‘现金’,
贝宝=‘贝宝’,
信用=‘信用’
}
const Cash=()=>({
种类:种类。现金作为种类。现金,
});
const PayPal=(电子邮件:字符串)=>({
kind:kind.PAYPAL作为kind.PAYPAL,
电子邮件
});
const CreditCard=(有效负载:{cardNumber:string,cvv:string})=>({
种类:种类。信用作为种类。信用,
有效载荷
});
类型PaymentMethod=ReturnType<
现金种类
|贝宝的类型
|信用卡类型
>;
函数描述PaymentMethod(方法:PaymentMethod):字符串{
开关(方法种类){
现金:
//这里,方法有Cash类型
归还“现金”;
case Kind.PAYPAL:
//这里,方法的类型是PayPal
返回`PayPal(${method.email})`;
案例种类.信用证:
//这里,方法有类型CreditCard
返回“信用卡(${method.payload.cardNumber})”;
}
}

假设您使用的是TypeScript 3.4或更高版本,您可以使用中的

要使
种类
属性的类型尽可能狭义地解释:

在TS3.4之前,或者在您不想使用
const
断言的情况下,您必须依赖TypeScript,例如以下帮助函数:

const lit = <T extends string | number | boolean | void | null | {}>(x: T) => x;


这两种方法都适合你。希望有帮助。祝你好运

如果你在TS3.4+上,你可以使用as in
kind:kind.CASH as const
@jcalz-这是一个可以接受的答案,让它成为一个,如果你关心一些业力,我会接受它。
const lit = <T extends string | number | boolean | void | null | {}>(x: T) => x;
const Cash = () => ({
  kind: lit(Kind.CASH)
});

const PayPal = (email: string) => ({
  kind: lit(Kind.PAYPAL),
  email
});

const CreditCard = (payload: { cardNumber: string; cvv: string }) => ({
  kind: lit(Kind.CREDIT),
  payload
});