如何将2个部分合并到Typescript中的完整对象?

Tom*_*Tom 6 typescript

在这里看到这个问题的游乐场

我有一个需要所有道具的界面。但是,创建对象是一个两步过程。因此,我计划创建Partial该对象的2个版本,然后将它们合并在一起以满足非局部接口。例:

interface IComplete {
    a: string,
    b: string
}

const part1: Partial<IComplete> = {
    a: 'hello'
}

const part2: Partial<IComplete> = {
    b: 'world'
}

const together: IComplete = {
    ...part1,
    ...part2
}
Run Code Online (Sandbox Code Playgroud)

即使together总是完成,编译器也会抱怨:

输入'{a ?: string; b ?:字符串;}”不可分配给“ IComplete”类型。属性'a'在类型'{a ?: string;中是可选的;b ?:字符串;}”,但在“ IComplete”类型中为必填。

有没有推荐的方法可以做到这一点?对于我的情况,重要的IComplete不要将接口设为局部。即道具a和b永远不会为null或未定义。

jca*_*alz 6

@RyanCavanaugh的答案很好。让类型推断完成其工作,同时还获得了编译器保证的收益的一种方式part1,并part2Partial<IComplete>是使用一个辅助功能如下:

interface IComplete {
  a: string,
  b: string,
  c: (x: string) => number,
  d: (x: number) => string
}

// helper function
const asPartialIComplete = <T extends Partial<IComplete>>(t: T) => t;

const part1 = asPartialIComplete({
  a: 'hello',
  c: (x) => x.length
})

const part2 = asPartialIComplete({
  b: 'world',
  d: (x) => x + ""
});

const together: IComplete = {
  ...part1,
  ...part2
}
Run Code Online (Sandbox Code Playgroud)

在上文中,part1part2均受asPartialIComplete有效Partial<IComplete>对象约束(因此,cd方法的参数分别推断为stringnumber)。但的类型part1part2对于编译器意识到足够窄,typeof part1 & typeof part2IComplete

希望对您有所帮助。祝好运!


Rya*_*ugh 5

最简单的方法是删除类型注释并让类型推断完成其工作:

interface IComplete {
    a: string,
    b: string
}

const part1 = {
    a: 'hello'
}

const part2 = {
    b: 'world'
}

const together: IComplete = {
    ...part1,
    ...part2
}
Run Code Online (Sandbox Code Playgroud)

part1这确实会产生某些有害影响,例如,函数表达式中的参数part2将无法获得推断类型。

相反,您可以使用Pick- 不幸的是,在使用此方法时,您必须写出从每种类型中选择的键:

interface IComplete {
    a: string,
    b: string,
    c: number
}

const part1: Pick<IComplete, "a"> = {
    a: 'hello'
}

const part2: Pick<IComplete, "b" | "c"> = {
    b: 'world',
    c: 43
}

const together: IComplete = {
    ...part1,
    ...part2
}
Run Code Online (Sandbox Code Playgroud)