当我将接口的任何属性设置为可选时,并将其成员分配给其他变量,如下所示:

interface Person {
  name?: string,
  age?: string,
  gender?: string,
  occupation?: string,
}

function getPerson() {
  let person = <Person>{name:"John"};
  return person;
}

let person: Person = getPerson();
let name1: string = person.name; // <<< Error here 

我得到如下错误:

TS2322: Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.

如何避免这个错误呢?


当前回答

你可以这样做!

let name1:string = `${person.name}`;

但是记住name1可以是空字符串

其他回答

也有同样的问题。

我发现react-scrips添加了“strict”:true到tsconfig.json。

在我移除它之后,一切都很好。

Edit

需要警告的是,更改此属性意味着:

不再对潜在的运行时错误发出警告。

正如保罗在评论中指出的那样!谢谢!

只有在你完全理解它的影响时才使用"strict": false !

如果你从getPerson函数中移除<Person>强制转换,那么TypeScript将足够聪明地检测到你返回的对象确实具有name属性。

所以只要转一下:

interface Person {
  name?: string,
  age?: string,
  gender?: string,
  occupation?: string,
}

function getPerson() {
  let person = <Person>{name: 'John'};
  return person;
}

let person: Person = getPerson();
let name1: string = person.name;

成:

interface Person {
  name?: string,
  age?: string,
  gender?: string,
  occupation?: string,
}

function getPerson() {
  let person = {name: 'John'};
  return person;
}

let person = getPerson();
let name1: string = person.name;

如果你不能这样做,那么你将不得不使用@yannick1976建议的“确定赋值断言操作符”:

let name1: string = person.name!;

这里有一个快速的方法来了解正在发生的事情:

当你做以下事情时:

的名字吗?:字符串

你对TypeScript说它是可选的。然而,当你这样做的时候:

let name1 : string = person.name; //<<<Error here 

你没有给它选择的余地。你需要在它上面有一个反映未定义类型的联合:

let name1 : string | undefined = person.name; //<<<No error here 

使用您的回答,我能够概述以下内容,基本上是一个接口,一个类和一个对象。我发现这种方法更简单,如果你不这样做也没关系。

// Interface
interface iPerson {
    fname? : string,
    age? : number,
    gender? : string,
    occupation? : string,
    get_person?: any
}

// Class Object
class Person implements iPerson {
    fname? : string;
    age? : number;
    gender? : string;
    occupation? : string;
    get_person?: any = function () {
        return this.fname;
    }
}

// Object literal
const person1 : Person = {
    fname : 'Steve',
    age : 8,
    gender : 'Male',
    occupation : 'IT'  
}

const p_name: string | undefined = person1.fname;

// Object instance 
const person2: Person = new Person();
person2.fname = 'Steve';
person2.age = 8;
person2.gender = 'Male';
person2.occupation = 'IT';

// Accessing the object literal (person1) and instance (person2)
console.log('person1 : ', p_name);
console.log('person2 : ', person2.get_person());

从TypeScript 3.7开始,你可以使用空合并运算符??您可以将此特性视为在处理null或未定义时“退回”到默认值的一种方式

let name1:string = person.name ?? '';

的? ?当尝试使用默认值时,操作符可以替换||的使用,并且可以在处理不能使用||的布尔值、数字等时使用。

从TypeScript 4开始,你可以使用??=赋值运算符作为??= b是a = a的替代??b;

你可以这样做!

let name1:string = `${person.name}`;

但是记住name1可以是空字符串