当我将接口的任何属性设置为可选时,并将其成员分配给其他变量,如下所示:
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'.
如何避免这个错误呢?
如果你从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!;
这是我发现的检查属性是否未定义而不生成警告的唯一解决方案
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
}
原来的答案