我可以逐步构建实现接口的对象吗?

4

我有一个类似如下的接口:

export interface Person {
  name: string;
  isMillenial: boolean;
}

同时,需要一个函数来输出该接口:

function makePerson(name: string, birthYear: number): Person {
  let newPerson = {
    name
  }

  // Calculate various properties, slowly building up the `newPerson` object
  newPerson.isMillenial = birthYear < 1981

  return newPerson
}

然而,这将会失败并出现以下错误:

类型 '{ name: string }' 中缺少属性 'isMillenial',但在类型 'Person' 中需要此属性。

我知道我可以在创建newPerson时声明所有属性以匹配预期的结果,但我想逐步构建正在创建的对象,一直添加属性,直到对象完成为止。在TypeScript中,是否有一种方法可以逐步构建对象并仍满足类型检查要求?
(如果答案是'否,你需要默认值',那也是可以接受的答案)
1个回答

2

是的,但你需要以不同的方式声明它,并且可能需要告诉TypeScript何时完成对象。 Partial实用类型基于另一个类型创建一个类型,使其所有属性都是可选的。所以:

function makePerson(name: string, birthYear: number): Person {
    let newPerson: Partial<Person> = {
    // −−−−−−−−−−−−^^^^^^^^^^^^^^^
        name
    };

    // Calculate various properties, slowly building up the `newPerson` object
    newPerson.isMillenial = birthYear < 1981;

    return newPerson as Person;
    // −−−−−−−−−−−−−−^^^^^^^^^
}

很遗憾,结尾处的类型断言是必需的(这让我感到惊讶,从上面可以看出两个属性在最后都不会是undefined,但TypeScript团队必须限制编译器的智能程度以防止它变得非常缓慢)。
返回值上的as Person也意味着如果你愿意,可以省略函数声明签名,TypeScript将知道函数的返回类型。 示例链接
function makePerson(name: string, birthYear: number): Person {
// Optional as far as TypeScript is concerned −−−−−−^^^^^^^^

尽管你可能希望保留它,如果函数超过几行,请确保不会添加新的return语句,以免改变返回类型。


你在问题中提到了它,但我想强调一下(也是为了潜水者),你可以先构建要用于创建对象的信息,然后一次性创建对象,以节省需要类型注释的步骤。这样可以简化示例的代码,但当然真实代码可能不会更简单:

function makePerson(name: string, birthYear: number): Person {
    const isMillenial = birthYear < 1981;
    return {name, isMillenial};
}

虽然这不总是可行的,但当它可行时我发现它很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接