用于验证特定对象的 Typescript 高级类型

Typescript Advanced Types to Validate Specific Objects

我正在尝试创建一些类型以便能够编写:

  1. MyObjectDetails — 定义 MyObject 结构
  2. MyObject - 正确遵循这些 MyObjectDetails 的对象。
// Details example
const testObjectDetails: MyObjectDetails = {
    name: 'Test',
    fields: [
        {
            name: 'property1'
        },
        {
            name: 'property2'
        }
    ]
}

// Object example
const testObject: MyObject<typeof testObjectDetails> = {
    property1: 123,
    property3: 456 // Should throw Error -> no such field in the details 
    // Should throw Error -> property2 is missing
}

我写了一些代码,但它们没有按预期工作:

type MyField = string extends infer T ? Readonly<{
  name: T
}> : never

type MyObjectDetails = Readonly<{
  name: string,
  fields: ReadonlyArray<MyField>
}>

type MyObject<T extends MyObjectDetails> = {
    [K in T['fields'][number]['name']]: any;
}

你能帮帮我吗?

这里的问题是testObjectDetails的声明。您正在使用 MyObjectDetails 类型声明它。执行此操作时,有关特定属性的所有类型信息都会丢失,因为 MyObjectDetails 不包含有关特定 属性 名称的详细信息。

解决此问题的一种方法是使用 as const 并删除类型 MyObjectDetails.

const testObjectDetails = {
    name: 'Test',
    fields: [
        {
            name: 'property1'
        },
        {
            name: 'property2'
        }
    ]
} as const

如果在声明 testObjectDetails 对象时仍然希望类型安全,则需要使用工厂函数:

const testObjectDetails = createTestObjectDetails({
    name: 'Test',
    fields: [
        {
            name: 'property1'
        },
        {
            name: 'property2'
        }
    ]
} as const)


function createTestObjectDetails<T extends MyObjectDetails>(testObjDetails: T) : T{
  return testObjDetails
}