Typescript 嵌套类型映射

标签 typescript

我正在尝试在 typescript 中处理模型验证。 我希望能够捕获验证定义的嵌套类型。

例如,我希望能够创建这样的验证器。

const validateUser = createValidator({
  name: {
    first: {
      value: "First"
    },
    last: {
      value: "Last"
    }
  },
  age: {
    value: 32
  },
  hasOnboarded: {
    value: false
  }
});

这将创建一个 validateUser 函数,该函数采用指定的模型 输入并验证其类型。

我希望能够捕获类型,以便 validateUser 知道接受, 符合接口(interface)的对象。

type ValidateUser = typeof validateUser;

应该是类型

(
  model: {
    name: {
      first: string,
      last: string
    },
    age: number,
    hasOnboarded: boolean
  }
) => boolean

这在 TypeScript 中可能吗?

最佳答案

确实如此,使用 2.8 的功能、条件类型和 infer关键字。

Playground

declare function createValidator<
  T extends {
    [key: string]: { value: any } | { [key: string]: { value: any } }
  }>(modelDescriptor: T): (validationSubject: {
    [key in keyof T]: T[key] extends { value: infer R }
    ? R
    : {
      [innerKey in keyof T[key]]: T[key][innerKey] extends { value: infer R } ? R : never
    }
  }) => boolean;

// const validateUser: (validationSubject: { name: { first: string; last: string; }; age: number; hasOnboarded: boolean; }) => boolean

const validateUser = createValidator({
  name: {
    first: {
      value: "First"
    },
    last: {
      value: "Last"
    }
  },
  age: {
    value: 32
  },
  hasOnboarded: {
    value: false
  }
});

让我们分解一下,因为这有点复杂。

首先,我们的函数接受类型参数 T ,其约束条件是它必须是一个对象,其中每个键必须是 {value: any}或一个嵌套对象,其中每个键都是这样的 {value: any} .

我们的返回类型是一个对象,这样对于 T 中的每个键,我们都会检查类型。如果是 {value: <whatever>} 类型,推断<whatever> (并称之为 R ),该键值的类型是 R (也称为 value 键下原始值的任何类型)。

如果不是 {value: <whatever>} 类型,那么根据我们最初的约束,它的类型必须是 {[key: string]: {value: <whatever>}} ,因此返回类型成为该内部对象的第二级映射,再次提取 value 中的任何内容的类型。嵌套对象的。

如果两者都不是(由于我们的限制,这是不可能的),则键的返回类型将为 never 。这部分永远不应该达到。

关于Typescript 嵌套类型映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53073110/

相关文章:

javascript - 如何在 Node.js 和 TypeScript 中构建可读流?

javascript - 对象数组的排序不适用于 Array.sort() 方法

javascript - 如何使用 Express .listen()(在 Typescript 中)处理错误?

angular - 在 Jasmine + Angular 中模拟 'window' 对象

javascript - 如何在像 forEach reduce 这样的 javascript 函数中使用 promise 函数?

javascript - TypeScript:你如何测试你的客户端代码?

javascript - Typescript - 将接口(interface)文字传递给函数参数

typescript - 类型 'User | undefined' 不可分配给类型 'User'

typescript - 如何使用 GET 方法获取并输入脚本

typescript - 什么是 typescript `--lib` 库文件?