我有一个接口Person,并且我能够通过一次分配所有属性来创建类型Person的对象user1

export interface person {
  name: string;
  age: number;
  city: string;

}

let user1: person = {
    name:"ron",
    age: 22,
    city:"AL"
}

有没有一种方法可以让我构建这个对象,而不是一次性分配所有属性.我正在找这样的东西

let user2:person;

user2.age = 22;
user2.name = "Dave";
user2.city = "NY"

推荐答案

在初始化值时,可以使用类型实用程序Partial<Type>来指示尚未定义属性:

let user: Partial<Person> = {};

在初始化属性值之后,TypeScrip将正确地推断它们确实存在:

user.age = 22;
user.name = "Dave";
user.city = "NY";

const doubleAge = user.age * 2; // Ok
const lowercaseCity = user.city.toLowerCase(); // Ok
const uppercaseName = user.name.toUpperCase(); // Ok

TS Playground

但是,如果您没有初始化其中一个属性值,则在try 使用该属性值时,TypeScrip将发出错误诊断:

let user: Partial<Person> = {};

user.age = 22;

const doubleAge = user.age * 2; // Ok

const lowercaseCity = user.city.toLowerCase(); /* Error
                      ~~~~~~~~~
'user.city' is possibly 'undefined'.(18048) */

const uppercaseName = user.name.toUpperCase(); /* Error
                      ~~~~~~~~~
'user.name' is possibly 'undefined'.(18048) */

TS Playground

在某些情况下,推理仍然不够-例如,当值需要用作需要Person的函数的参数时:

declare function doSomethingWithPerson(person: Person): void;

let user: Partial<Person> = {};

user.age = 22;
user.name = "Dave";
user.city = "NY";

doSomethingWithPerson(user); /* Error
                      ~~~~
Argument of type 'Partial<Person>' is not assignable to parameter of type 'Person'.
  Property 'name' is optional in type 'Partial<Person>' but required in type 'Person'.(2345) */

TS Playground

在这些情况下,您可以创建一个名为type guard的函数,该函数将在运行时进行判断,以确保类型满足声明的期望.用户定义的类型保护是返回类型为type predicate的函数:

function isPerson<T extends Record<PropertyKey, unknown>>(
  p: T,
): p is T & Person {
  return (
    typeof p.age === "number" &&
    typeof p.city === "string" &&
    typeof p.name === "string"
  );
}

另请参阅手册:generics

然后您可以在使用前判断user是否确实符合Person的定义,以避免错误:

let user: Partial<Person> = {};

user.age = 22;
user.name = "Dave";
user.city = "NY";

if (isPerson(user)) {
  doSomethingWithPerson(user); // Ok
} else {
  // Handle the other case here
}

TS Playground

Javascript相关问答推荐

如何修复循环HTML元素附加函数中的问题?

node TS:JWT令牌签名以验证客户端和后台问题之间的身份验证

GrapeJS -如何保存和加载自定义页面

被CSS优先级所迷惑

阿波罗返回的数据错误,但在网络判断器中是正确的

在JS中拖放:检测文件

我怎么在JS里连续加2个骰子的和呢?

在浏览器中触发插入事件时检索编码值的能力

基于props 类型的不同props ,根据来自接口的值扩展类型

SPAN不会在点击时关闭模式,尽管它们可以发送日志(log)等

回溯替代方式

如果没有页面重新加载Angular ,innerHTML属性绑定不会更新

AddEventListner,按键事件不工作

Next.js中的服务器端组件列表筛选

如何使用Astro优化大图像?

使用RxJS from Event和@ViewChild vs KeyUp事件和RxJS主题更改输入字段值

在Java脚本中录制视频后看不到曲目

有没有办法通过使用不同数组中的值进行排序

AG-GRIDreact 显示布尔值而不是复选框

如何在不将整个文件加载到内存的情况下,在Node.js中实现Unix粘贴命令?