我遇到了一些对我来说似乎很奇怪的行为。
在下面的示例中,我有两个函数,它们以一个对象作为输入并返回具有相同键但值不同的对象。使用useForm1
时可以得到预期的结果。我可以访问输入对象的属性键,并且它也具有正确的值(Field
)。
但是,当使用useForm2
(使用Form<T>
而不是内联的{ [P in keyof T]: Field }
并乍看起来实际上是相同的)时,我也得到了一个具有键的对象不幸的是,值不是输入对象Field
的类型,而是普通对象(又称{}
,没有任何属性。)。
任何人都可以解释为什么这两种方法产生不同的结果以及如何调整useForm2
的定义吗?
type FormConfig<T> = {
[P in keyof T]: {
required?: boolean;
validator?: (input: string) => void | Promise<void>;
type: string;
}
};
type Field = {
required?: boolean;
name: string;
type: string;
value: string;
};
type Form<T> = { [P in keyof T]: Field };
export const useForm1 = <T extends Object>(
config: FormConfig<T>
): { [P in keyof T]: Field } => {
// do some logic
};
export const useForm2 = <T extends Object>(config: FormConfig<T>): Form<T> => {
// do some logic
};
const test1 = useForm1({
login: {
type: "text"
}
});
const test2 = useForm2({
login: {
type: "text"
}
});
答案 0 :(得分:0)
Object
是一种非常通用的类型,几乎不应在TypeScript中使用。在这种情况下,您希望将键值映射作为输入并返回经过处理的键-值映射,因此这是您应在所有约束中指定的类型:
type Form<T extends Record<string, any>> = { [P in keyof T]: Field };
export const useForm1 = <T extends Record<string, any>>(
config: FormConfig<T>
): { [P in keyof T]: Field } => {
// do some logic
return null as any
};
export const useForm2 = <T extends Record<string, any>>(config: FormConfig<T>): Form<T> => {
// do some logic
};
test2.login.required // works