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

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'.

如何避免这个错误呢?


当前回答

在我的特定情况下发生在我身上的一件事(但它与这里问到的具体问题无关)是,我在文件中导入了错误的类型,因为类型被称为完全相同,但定义了不同的属性。

一旦我导入了正确的类型,所有的问题都消失了。

我希望这能帮助那些和我面临同样问题的人。

其他回答

  @Input()employee!:string ;
announced:boolean=false;
confirmed:boolean=false;
task:string="<topshiriq yo'q>";

  constructor(private taskService:TaskService ) {
    taskService.taskAnnon$.subscribe(
      task => {
        this.task=task;
        this.announced=true;
        this.confirmed=false;
      }
    )
  }

  ngOnInit(): void {
  }
  confirm(){
   this.confirmed=true
   this.taskService.confirimTask(this.employee);
  }
}

我知道这有点晚了,但是除了yannick的答案,还有另一种方法可以使用!是将它转换为字符串,从而告诉TypeScript:我确定这是一个字符串,从而转换它。

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

to

let name1:string = person.name as string;

这将使错误消失,但如果这不是一个字符串,你将得到一个运行时错误…这也是我们使用TypeScript来确保类型匹配并在编译时避免此类错误的原因之一。

你试图设置变量name1,女巫类型设置为严格的字符串(它必须是字符串),值从对象字段名,女巫值类型设置为可选字符串(它可以是字符串或未定义,因为问题符号)。如果你真的需要这种行为,你必须像这样改变name1的类型:

let name1: string | undefined = person.name;

一切都会好的;

这是我发现的检查属性是否未定义而不生成警告的唯一解决方案

type NotUndefined<T, K extends keyof T> = T & Record<K, Exclude<T[K], undefined>>;
function checkIfKeyIsDefined<T, K extends keyof T>(item: T, key: K): item is NotUndefined<T, K> {
    return typeof item === 'object' && item !== null && typeof item[key] !== 'undefined';
}

用法:


interface Listing { 
    order?: string
    ...
}
obj = {..., order: 'pizza'} as Listing
if(checkIfKeyIsDefined(item: obj, 'order')) {
    order.toUpperCase() //no undefined warning O.O
}

原来的答案

为了避免我使用的编译错误

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

然后验证空字符串。