如何使用 TypeScript 正确键入检查允许部分子树的嵌套记录?
How to properly type check nested records allowing partial subtrees with TypeScript?
请看下面的演示。
interface Data
定义嵌套数据的模式。
function check
应验证此 Data
结构的给定部分子树是否正常,如果不正常则抛出编译时错误(希望有或多或少详细且易于理解的错误消息,而不仅仅是“......不能分配给类型“从不”)。
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'
}
})
您不需要 check
函数。直接使用可选字段。
interface Data {
namespace1?: {
keyA?: string,
keyB?: string
},
namespace2?: {
keyC?: string,
keyD?: string
}
}
const validPartialData1:Data = {
namespace1: {
keyB: 'b'
}
}
如果您不想更改 Data
类型。您可以定义另一个 PartialData
type NestPartial<T> = {
[P in keyof T]?: NestPartial<T[P]>;
}
type PartialData = NestPartial<Data>
const validPartialData1: PartialData = {
namespace1: {
keyB: 'b'
}
}
请看下面的演示。
interface Data
定义嵌套数据的模式。
function check
应验证此 Data
结构的给定部分子树是否正常,如果不正常则抛出编译时错误(希望有或多或少详细且易于理解的错误消息,而不仅仅是“......不能分配给类型“从不”)。
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'
}
})
您不需要 check
函数。直接使用可选字段。
interface Data {
namespace1?: {
keyA?: string,
keyB?: string
},
namespace2?: {
keyC?: string,
keyD?: string
}
}
const validPartialData1:Data = {
namespace1: {
keyB: 'b'
}
}
如果您不想更改 Data
类型。您可以定义另一个 PartialData
type NestPartial<T> = {
[P in keyof T]?: NestPartial<T[P]>;
}
type PartialData = NestPartial<Data>
const validPartialData1: PartialData = {
namespace1: {
keyB: 'b'
}
}