【发布时间】:2020-08-14 13:39:04
【问题描述】:
我正在尝试从包含本机类型验证函数的对象中提取类型映射,例如,如果我有该对象
const test = {
Test: {
Test1: {
Test2: SimpleStringValidator //return type is string or undefined but input can be anything
},
}
}
我要提取类型
type Extracted = {
Test: {
Test1: {
Test2: string
}
}
}
为此,我编写了以下代码来提取包含一组嵌套验证函数的对象的返回类型
Sample.ts
export type Validator<T> = NativeTypeValidator<T> | ObjectValidator<T>
export type NativeTypeValidator<T> = (n: any) => T | undefined
export type ObjectValidator<O> = {
[K in keyof O]: Validator<O[K]>
}
//native validators
export const SimpleStringValidator:NativeTypeValidator<string> = (val) => typeof(val) === "string" ? val : undefined
//object validator function
export const ObjValidator = <V>(validatorObj: ObjectValidator<V>) => (o:any):V =>{
let result = {} as V;
//we can only validate objects
if (typeof (o) !== "object") { return undefined; }
const validatorKeys = Object.keys(o) as [keyof ObjectValidator<V>]
validatorKeys.forEach((validatorKey) => {
const objValue = o[validatorKey] as V[keyof V];
const objectValidator = validatorObj[validatorKey]
if (!objectValidator) { return undefined } //do nothing if no validator exists for the key in o
//figure out if we have a nested object validator or a native validator at the corresponding key of validatorObj
if (typeof (objectValidator) === "object") {
result[validatorKey] = ObjValidator(objectValidator as ObjectValidator<V[keyof V]>)(objValue)
}
else {
const nativeValidator = objectValidator as NativeTypeValidator<V[keyof V]>;
result[validatorKey] = nativeValidator(objValue)
}
})
return result;
}
export const test = {
Test: {
Test1: {
Test2: SimpleStringValidator
},
}
}
export const validatorFunc = ObjValidator(test);
export const outputExample = validatorFunc({
Test: {
Test1: {
Test2: "hi"
},
}
})
outputExample.Test.Test1.Test2 = "1";
outputExample.Test.Test1.Test2 = 1; //vs code intellisense complains because needs to be type string
在我的例子中,intellisense 自动完成嵌套属性 Test2 并将类型作为字符串,但是当我创建类型声明文件时,类型信息是不同的,我无法将此生成的类型正确导出到其他项目。具体来说,它将属性 Test1 的类型设置为 any。我要生成的类型是上面代码中validatorFunc的输出和outputExample的类型。
生成的样本.d.ts
export declare type Validator<T> = NativeTypeValidator<T> | ObjectValidator<T>;
export declare type NativeTypeValidator<T> = (n: any) => T | undefined;
export declare type ObjectValidator<O> = {
[K in keyof O]: Validator<O[K]>;
};
export declare const SimpleStringValidator: NativeTypeValidator<string>;
export declare const ObjValidator: <V>(validatorObj: ObjectValidator<V>) => (o: any) => V;
export declare const test: {
Test: {
Test1: {
Test2: NativeTypeValidator<string>;
};
};
};
export declare const validatorFunc: (o: any) => {
Test: {
Test1: any;
};
};
export declare const outputExample: {
Test: {
Test1: any;
};
};
我需要使用根验证器对象作为我提取的类型的源,以寻找生成的声明文件具有正确类型的解决方案。我在 Typescript 操场上有这段代码,它显示了自动完成和放入 .d.ts 文件的内容之间的区别。
【问题讨论】:
标签: typescript typescript-generics