0

我有一个带有类型保护和函数剩余参数的 Typescript 示例:

interface BaseProps {
  username: string;
  password: string;
}

type Props = BaseProps & (
  | {isAdmin: true, adminName: string} 
  | {isAdmin: false}
)


// Doesn't works
const myFn = ({isAdmin, ...rest}: Props) => {
  if(isAdmin === true) {
    rest.adminName; // Property 'adminName' does not exist on type '{ username: string; adminName: string; } | { username: string; }'.
  }
}

// It works
const myFn2 = (args: Props) => {
  if(args.isAdmin === true) {
    args.adminName;
  } 
}

其余参数和类型保护有什么问题?

TS游乐场


更新解决方案:

我找到了解决方案,Assert Functions用于解决问题。

declare function assertType<T>(val: unknown): asserts val is T;

const myFn = ({password, isAdmin, ...rest}: Props) => {

  if(isAdmin === true) {
    
    assertType<Omit<Props & {isAdmin: true}, keyof Props>>(rest);

    rest.adminName; // <=== HERE

    rest.username;

    // Should be error
    rest.password;
  }
}

TS游乐场

4

1 回答 1

0

的类型Props

{ 用户名:字符串,isAdmin:真,管理员名称:字符串 } | {用户名:字符串,isAdmin:假}

isAdmin当您在类型对象Prop(例如语句)上断言 的值时if,打字稿能够缩小 和 之间的实际{ username: string, isAdmin: true, adminName: string }类型{ username: string, isAdmin: false }

如果isAdmin通过解构删除,则类型rest变为

{ 用户名:字符串,管理员名称:字符串 } | {用户名:字符串}

isAdminrest变得不相关,缩小类型的唯一方法rest是断言adminName属性的存在。

也许您不应该在这种特定情况下使用休息参数。您也可以restif.

于 2020-10-27T09:15:35.423 回答