让我解释一下。我有以下用例:在 Angular 中,我使用表格 UI 组件,它看起来如下所示:
<my-table [values]="myTableValues">
<my-column field="firstColumn" />
</my-table>
myTableValues
它的行有一个类型(我们称之为myTableValuesRowType
),它是通过 swagger-code 生成器生成的。如您所见,它field
以字符串作为值,这使其类型不那么严格。
我想到了一个解决方案,它创建具有相同属性的类型的对象并返回每个键的字符串值。基本上是这样的:
[Key]: KeyString
这是我的代码:
type NonNullableKeys<T> = {
[K in keyof T]: T[K] extends null | undefined ? never : K;
}[keyof T];
export type PropertiesOf<T> = Record<NonNullableKeys<T>, string>;
export function getTypeProperties<T>(): PropertiesOf<T> {
return new Proxy({}, {
get: (_target, prop: string) => prop,
}) as PropertiesOf<T>;
}
这让我们更容易使field
html 模板中的属性更加严格。这可能不是最好的解决方案,但它是我们现在可以使用的最好/最简单的解决方案。示例用法:
//component.ts
readonly rowProperties = getTypeProperties<myTableValuesRowType>();
//component.html
<my-table [values]="myTableValues">
<my-column [field]="rowProperties.firstColumn" />
</my-table>
这样,如果生成的类型改变了属性键,我就能够立即检测到它。
然而有一个主要问题,上面的函数不是递归的。因此嵌套属性将被忽略。
例子:
type myTableValuesRowType = {
firstColumn: number;
secondColumn: string;
thirdColumn: number[];
fourthColumn: boolean;
subrow: {
firstSubrowColumn: string;
secondSubrowColumn: number;
}
}
const rowProperties = getTypeProperties<myTableValuesRowType>();
console.log(rowProperties.firstColumn); //returns "firstColumn"
console.log(rowProperties.subrow.firstSubrowColumn); //returns undefined & TS-Error: Property 'firstSubrowColumn' does not exist on type 'string'. expecting to return "subrow.firstSubrowColumn"
最后我的问题是,我怎样才能使它递归?我尝试了多种方法,并做了一些研究,以找到类似的东西。我发现的只是在另一种类型中获取嵌套键,但并没有真正提取属性并创建它的对象。
仅供参考,我无法更改 UI 组件库...
我将不胜感激任何帮助或见解!
更新:我发现了一些非常相似的东西,但是它将其转换为一个函数,而且看起来不像一个对象那么好。
另一个更新:我忘了说我希望rowProperties.subrow.firstSubrowColumn
返回subrow.firstSubrowColumn
,而不仅仅是子键firstSubrowColumn