首页 > 解决方案 > 验证元组

问题描述

我有一个类型Job

const days = ['Monday', 'Wednesday'] as const
type Day = typeof days[number]

const isValidDay = (value: string): value is Day => value in days

const statuses = ['start', 'end'] as const
type Status = typeof statuses[number]

const isValidStatus = (value: string): value is Status => value in statuses

type Job = [Day, Status]

我想编写一个函数来验证参数是否符合类型Job

鉴于我会像这样使用这个验证器

const main = (value: string) => {
  const job = value.split('/')
  if (!isValidJob(job)) {
    throw new Error('Not a job')
  }

  // ...
}

我认为isValidJob应该实施类似

const isValidJob = (value: Array<string>): value is Job => {
  return value.length === 2 && isValidDay(value[0]) && isValidStatus(value[1])
}

但是即使这个验证器没有断言value符合Job,以下也不会标记任何问题,也value[1]不会是一个数字

const isValidJob = (value: any): value is Job => {
  return typeof value[1] === 'number'
}

所以我的问题是,我应该如何验证jobtype Job

标签: typescript

解决方案


返回类型谓词的函数只需要在运行时返回一个布尔值。这就是它们的工作方式 - 您断言所提供的验证对于该特定类型是正确的。您最初的实现isValidJob看起来会很好地做到这一点。Array.isArray如果您想将value参数键入为any或,您可以添加一个检查unknown

但是,我不认为前面的两个守卫是正确的。in 运算符为对象属性和数组索引返回 true,而不是数组中的元素。例如:

isValidDay("Monday") // false
isValidDay("length") // true
isValidDay(0) // fails TS check but returns true

您可以使用以下方法处理此问题Array.some

const isValidDay = (value: string): value is Day => days.some(d => d === value);

推荐阅读