如何从 TypeScript 中的通用部分构建目标对象?

2024-03-19

我在用[电子邮件受保护] /cdn-cgi/l/email-protection.

我有一个目标对象:

interface MyTarget {
    a: string;
    b: string;
    c: string;
    d: string;
}

我想使用泛型创建部分对象的多个转换。

一种这样的转换可能如下所示:

const convert = <T extends object>(t: T): MyTarget => {
    return {
        c: "c",
        d: "d",
        ...t,
    };
};

然而这会导致:

error TS2698: Spread types may only be created from object types.

即使我守护通用T成为一个object.

然后我想起来有一个Partial类型,因此我尝试了这个:

const convert = (partial: Partial<MyTarget>): MyTarget => {
    return {
        c: "c",
        d: "d",
        ...partial,
    };
};

Yet the Partial使所有属性可选。我不想要这样,它现在会抛出:

src/Partial.ts(14,5): error TS2322: Type '{ a?: string; b?: string; c: string; d: string; }' is not assignable to type 'MyTarget'.
  Property 'a' is optional in type '{ a?: string; b?: string; c: string; d: string; }' but required in type 'MyTarget'.

我想创建一个实例MyTarget每个字段都设置为要求。我确实想保持类型安全,这就是为什么我不想这样做,即使它有效:

const convert = (partial: Partial<MyTarget>): MyTarget => {
    return {
        c: "c",
        d: "d",
        ...partial,
    } as MyTarget; // loses type checks, really don't want to
};

我认为您使用的是旧版本的 TS(在新版本中,扩展表达式输入正确)。

不管怎样,真正的问题是对象字面量可能不是完整的MyTarget。您的代码将允许此调用

convert({a : "" })// return value is not really MyTarget since it will not contain b

你真正想要的是参数MyTarget except c and d:

interface MyTarget {
    a: string;
    b: string;
    c: string;
    d: string;
}
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
const convert = (t: Omit<MyTarget, 'c' | 'd'>) : MyTarget => {
    return {
        c: "c",
        d: "d",
        ...t,
    };
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 TypeScript 中的通用部分构建目标对象? 的相关文章

随机推荐