如何使用 TypeScript 正确键入检查允许部分子树的嵌套记录?

Posted

技术标签:

【中文标题】如何使用 TypeScript 正确键入检查允许部分子树的嵌套记录?【英文标题】:How to properly type check nested records allowing partial subtrees with TypeScript? 【发布时间】:2022-01-02 10:35:21 【问题描述】:

请看下面的演示。interface Data 定义嵌套数据的模式。function check 将验证此Data 结构的给定部分子树是否正常并引发编译-time 错误,如果不是(希望有一个或多或少详细且易于理解的错误消息,而不仅仅是“......不可分配给类型'never”)。

interface Data 
  namespace1: 
    keyA: string,
    keyB: string
  ,

  namespace2: 
    keyC: string,
    keyD: string
  


// This function's only purpose is to perform a compile-time check
// whether the given partial data is valid.
// Returns the first and only argument in case of success,
// otherwise a compile-time error will occur.
function check<??>(
  partialData: ????
): ?????? 
  return partialData


// Example 1 => okay
const validPartialData1 = check(
  namespace1: 
    keyB: 'b'
  
)

// Example 2 => okay
const validPartialData2 = check(
  namespace1: 
    keyB: 'b'
  ,

  namespace2: 
    keyC: 'c'
  
)

// Example 3 => okay
const validPartialData3 = check()

// Example 4 => compile-time error!
const invalidPartialData1 = check(
  namespace1: 
    keyC: 'c'
  
)

// Example 5 => compile-time error!
const invalidPartialData2 = check(
  xyz: 
    keyA: 'a'
  
)

【问题讨论】:

【参考方案1】:

您不需要check 函数。直接使用可选字段。

interface Data 
  namespace1?: 
    keyA?: string,
    keyB?: string
  ,

  namespace2?: 
    keyC?: string,
    keyD?: string
  


const validPartialData1:Data = 
  namespace1: 
    keyB: 'b'
  

见playground

如果您不想更改Data 类型。你可以定义另一个PartialData

type NestPartial<T> = 
    [P in keyof T]?: NestPartial<T[P]>;

type PartialData = NestPartial<Data>

const validPartialData1: PartialData = 
    namespace1: 
        keyB: 'b'
    

见playground

【讨论】:

以上是关于如何使用 TypeScript 正确键入检查允许部分子树的嵌套记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 TypeScript 正确键入 Sequelize JOIN?

如何使用 Typescript 在 mongoose 中正确键入对象 ID 数组

如何使用 Typescript 在 mongoose 中正确键入对象 ID 数组

如何在 TypeScript 3+ 中正确键入通用元组剩余参数?

如何正确键入返回 TypeScript 中的类的函数?

TypeScript:如何正确键入一个接受承诺并按原样返回该承诺的函数