gpt4 book ai didi

javascript - TypeScript 映射类型推断未按预期工作

转载 作者:行者123 更新时间:2023-12-02 23:50:36 24 4
gpt4 key购买 nike

鉴于此功能:

export const combineValidators = <Input extends { [P in keyof Input]: (val: string) => Err }, Err>(
validators: Input
) => (values: { [P in keyof Input]?: unknown }): { [P in keyof Input]: Err } => {
// Ignore implementation.
return {} as { [P in keyof Input]: Err };
};

这个用法:

const validator = combineValidators({
name: (val) => val ? undefined : 'error',
email: (val) => val ? undefined : 'error'
});

const errors = validator({
name: 'Lewis',
email: 'lewis@mercedes.com'
});

我希望 TypeScript 能够将返回类型推断为:

// Expected: `errors` to be inferred as:
interface Ret {
name: string | undefined;
email: string | undefined;
}

但是推断为:

// Actual: `errors` inferred as:
interface Ret {
name: {};
email: {};
}

我创建了一个 live example in the TypeScript playground演示该问题。

有人可以帮忙吗?

最佳答案

Err 不会按照您期望的方式推断。使用 ReturnType 条件类型从 Input 中提取返回类型可能会更简单:

type ReturnTypes<T extends Record<keyof T, (...a: any[]) => any>> = {
[P in keyof T]: ReturnType<T[P]>
}

export const combineValidators = <Input extends Record<keyof Input, (val: unknown) => any>>(
validators: Input
) => (values: Record<keyof Input, unknown>): ReturnTypes<Input> => {
return {} as ReturnTypes<Input>;
};

const validator = combineValidators({
name: (val) => val ? undefined : 'error',
email: (val) => val ? undefined : 'error'
});

const errors = validator({
name: 'Lewis',
email: 'lewis@mercedes.com'
});

我们甚至可以更进一步,如果您在验证器函数中指定参数类型,则可以对传递给验证器的对象字段进行类型检查:

type ParamTypes<T extends Record<keyof T, (a: any) => any>> = {
[P in keyof T]: Parameters<T[P]>[0]
}

type ReturnTypes<T extends Record<keyof T, (...a: any[]) => any>> = {
[P in keyof T]: ReturnType<T[P]>
}

export const combineValidators = <Input extends Record<keyof Input, (val: unknown) => any>>(
validators: Input
) => (values: ParamTypes<Input>): ReturnTypes<Input> => {
return {} as ReturnTypes<Input>;
};

const validator = combineValidators({
name: (val: string) => val ? undefined : 'error',
email: (val) => val ? undefined : 'error', // if we leave it out, we still get unknown
age: (val: number) => val ? undefined : 'error'
});

const errors = validator({
name: 'Lewis',
email: 'lewis@mercedes.com',
age: 0
});

const errors2 = validator({
name: 'Lewis',
email: 'lewis@mercedes.com',
age: "0" // type error
});

关于javascript - TypeScript 映射类型推断未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55666545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com