【问题标题】:Is it possible to create an "empty" object from a TypeScript interface?是否可以从 TypeScript 接口创建一个“空”对象?
【发布时间】:2020-08-23 23:35:12
【问题描述】:

假设你有一个非常大的对象定义为 TypeScript 接口:

interface AccountInterface {
  accountIdentifier?: string;
  sid?: string;
  idToken?: {
    aio?: string;
  };
  idTokenClaims?: {
      aio?: string;
  };
}

我希望对象始终具有其属性和子属性。它们可以是字符串或空字符串:

let account = {
  accountIdentifier: "",
  sid: "",
  idToken: {
    aio: "",
  },
  idTokenClaims: {
    aio: "",
  },
};

阅读我认为可以这样做的其他问题:

const emptyAccount = {} as AccountInterface

console.log('emptyAccount ', emptyAccount)
console.log('emptyAccount.sid ', emptyAccount.sid)

但这并不会根据需要创建一个所有属性都为空字符串的对象。

如果这样的事情是可能的,那就太好了,所以不需要在代码中复制对象,就像一个用于接口,一个用于具有空字符串属性的对象。

【问题讨论】:

  • 我认为 typescript 中没有“与接口匹配的默认值”功能,而且我也看不到任何自动提供这种功能的明智方法。为什么默认为空字符串?如果类型是string|number|null,那么默认值是什么。如果该值是可选的(在您的情况下它们都是可选的)是默认的 undefined 或类型的默认值(如果存在),如果存在,那么为什么它是可选的?
  • "阅读其他问题" - 哪些?请链接它们。
  • 我是 TS 新手,所以仍然在这里学习。更新了问题。

标签: javascript typescript constructor interface typescript-typings


【解决方案1】:

您可以创建一个class that implements that interface,添加默认值,然后使用它来创建您的对象。您仍在其他地方重写相同的结构,但现在您只需执行一次,如果您愿意,您可以使用 constructor 用不同的值初始化您的对象。

interface AccountInterface {
  accountIdentifier?: string;
  sid?: string;
  idToken?: {
      aio?: string;
  };
  idTokenClaims?: {
      aio?: string;
  };
}

class Account implements AccountInterface {
  accountIdentifier = '';
  sid = '';
  idToken = { aio: '' };
  idTokenClaims = { aio: '' };
}

const emptyAccount = new Account();

另外,正如@apokryfos 所指出的,您还可以使用该类来键入对象,因此无需同时定义instanceclass,除非您要让实现该实例的对象没有' 不是使用类创建的(因为那些不会有类中定义的方法)。

如果你想避免使用class 并使用function 做类似的事情,你完全可以:

function createAccount(): AccountInterface {
  return {
    accountIdentifier = '';
    sid = '';
    idToken = { aio: '' };
    idTokenClaims = { aio: '' };
  };
}

const emptyAccount = createAccount();

【讨论】:

  • 你根本不需要界面。您可以在类中声明类型,然后 TypeScript 很乐意根据上下文将该类用作类型和值
  • 可以在没有class 的情况下完成吗?我想尽可能使用函数。
  • 是的,没错。我只是假设出于某种原因该界面无论如何都会存在。也许您的对象可能具有那些不是类实例的属性。
  • 我们的目标实际上是避免输入两次对象属性。这就是为什么我想从界面实例化对象而不用再次输入。
  • 检查!谢谢:) 我只是认为如果不重新输入属性名称就可以做到这一点。然后关闭这个,再次感谢大家的帮助。
【解决方案2】:

const emptyAccount = {} as AccountInterface 应该创建一个对象。但是您的 AccountInterface 仅包含可能存在但不能存在的属性(因为?)。所以空对象完全匹配您的 AccountInterface。

如果您想包含一个具有默认值的属性,那么您必须在您的界面中声明它。

interface AccountInterface {
    accountIdentifier: string|null // <- will be included in {} as AccountInterface
    sid?: string // <- will not be included in {} as AccountInterface
}

【讨论】:

  • emptyAccount 对象仍然没有accountIdentifier 属性,即使去掉所有问号。
猜你喜欢
  • 2020-05-02
  • 2020-08-26
  • 2011-03-11
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 2010-11-13
相关资源
最近更新 更多