我有一个由嵌套数组和对象组成的任意结构,ValidationError对象为叶子。要输入此内容,我需要一个Typescript guidelines中所示的递归类型。
虽然赋值(const x = ...
)通过了类型检查,但是访问结构(x.errors.a
)却出现了TypeScript错误,我无法理解:
错误:TS2339:类型'ValidationResultElement'上不存在属性'a'。
类型'ValidationResultObject'上不存在属性'a'。
see code on 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);
答案 0 :(得分:1)
您需要缩小类型。这是一个例子,但我有警告!
function isValidationResultObject(obj: any): obj is ValidationResultObject {
return (obj && (!obj.type) && (!obj.length));
}
if (isValidationResultObject(x.errors)) {
console.log(x.errors.a);
}
我已经定制了一个自定义类型防护以消除其他类型,但这可能是错误的,它只是演示了这个概念。您需要编写一个有效的类型防护。
您可能会发现,有区别的联合类型使研究大量属性变得更加容易。
您可以使用断言来强制缩小类型,但是类型保护更为诚实,可以确保您确实在处理所需的类型。