[英]How to correctly do recursive type definition in TypeScript?
I have an arbitrary structure consisting of nested arrays and objects, with ValidationError objects as leaves.我有一个由嵌套数组和对象组成的任意结构,其中 ValidationError 对象作为叶子。 To type this I need a recursive type as shown in Typescript guidelines .
要键入此内容,我需要一个递归类型,如Typescript 指南中所示。
While the assignment ( const x = ...
) seems to pass the type check, accessing the structure ( x.errors.a
) gives a TypeScript error which I cannot understand:虽然赋值(
const x = ...
)似乎通过了类型检查,但访问结构( x.errors.a
)会产生一个我无法理解的 TypeScript 错误:
Error: TS2339: Property 'a' does not exist on type 'ValidationResultElement'.
错误:TS2339:类型“ValidationResultElement”上不存在属性“a”。
Property 'a' does not exist on type 'ValidationResultObject'.
类型“ValidationResultObject”上不存在属性“a”。
see code on TypeScript Playground 在 TypeScript Playground 上查看代码
export interface ValidationResult {
errors: ValidationResultElement;
}
type ValidationResultElement =
ValidationResultObject | ValidationResultArray | ValidationError;
interface ValidationResultArray extends Array<ValidationResultElement> {
}
interface ValidationResultObject {
[key: string]: ValidationResultElement;
}
interface ValidationError {
details: string;
}
// This works:
const x: ValidationResult = {
errors: { a: { b: [{ c: { details: 'foo' } }] } }
};
// This produces a type error:
console.log(x.errors.a);
You need to narrow the type.您需要缩小类型。 This is an example but I have caveats!
这是一个例子,但我有警告!
function isValidationResultObject(obj: any): obj is ValidationResultObject {
return (obj && (!obj.type) && (!obj.length));
}
if (isValidationResultObject(x.errors)) {
console.log(x.errors.a);
}
I have chucked together a custom type guard to eliminate the other types, but it is probably wrong, it just demonstrates the concept.我已经将自定义类型保护放在一起以消除其他类型,但这可能是错误的,它只是演示了这个概念。 You need to write a type guard that works.
您需要编写一个有效的类型保护。
You may find a discriminated union type makes this easier that delving into lots of properties.您可能会发现有区别的联合类型使深入研究许多属性更容易。
You could force the type to narrow with an assertion, but a type guard is more honest and ensures you are really dealing with the type you expect.您可以通过断言强制类型缩小,但类型保护更诚实并确保您真正处理您期望的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.