是否可以从 TypeScript 接口创建一个“空”对象?

Posted

技术标签:

【中文标题】是否可以从 TypeScript 接口创建一个“空”对象?【英文标题】:Is it possible to create an "empty" object from a TypeScript interface? 【发布时间】: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 新手,所以仍然在这里学习。更新了问题。 【参考方案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 属性,即使去掉所有问号。

以上是关于是否可以从 TypeScript 接口创建一个“空”对象?的主要内容,如果未能解决你的问题,请参考以下文章

Typescript 基于接口从另一个对象创建一个对象

从 JavaScript 到 TypeScript - 接口

TypeScript 从现有接口创建新接口并更改所有属性的类型

如何故意在打字稿中定义一个“空接口”

React Typescript 类组件默认道具接口

如何从接口中省略一个属性,而不是 TypeScript 中的类型?