Машинопись: Тип 'строка | undefined 'нельзя назначить типу' string '

Когда я делаю любое свойство интерфейса необязательным, я получаю сообщение об ошибке, подобное следующему при назначении его члена какой-либо другой переменной

TS2322: Тип 'строка | undefined 'нельзя назначить типу' string '. Тип 'undefined' нельзя назначить типу 'string'.

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 

Как мне обойти эту ошибку?

Ответ 1

Теперь вы можете использовать оператор ненулевого утверждения, который здесь именно для вашего случая использования.

Он говорит машинописи, что, хотя что-то выглядит так, как будто оно может быть нулевым, оно может поверить, что это не так:

let name1:string = person.name!; 
//                            ^ note the exclamation mark here  

Ответ 2

Чтобы избежать ошибки компиляции я использовал

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

И затем проверьте пустую строку.

Ответ 3

Постарайтесь заранее выяснить, что является действительным значением. Если у person есть действительное name, присвойте ему name1, иначе назначьте undefined.

let name1: string = (person.name) ? person.name : undefined;

Ответ 4

Я знаю, что это довольно поздний ответ, но другой способ, кроме янничного ответа, использовать fooobar.com/questions/17021639/... ! чтобы привести его как строку, таким образом говоря TypeScript, я уверен, что это строка, таким образом преобразуя

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

в

let name1:string = person.name as string;

Это устранит ошибку, но если по какой-либо причине это не строка, вы получите ошибку времени выполнения, которая является одной из причин, по которым мы используем TypeScript, чтобы убедиться, что тип соответствует и избегайте таких ошибок во время компиляции.

Ответ 5

Решение 1. Удалите явное определение типа

Поскольку getPerson уже возвращает Person с именем, мы можем использовать выведенный тип.

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

let person = getPerson();

Если бы мы определяли person: Person мы бы потеряли часть информации. Мы знаем, что getPerson возвращает объект с необязательным свойством с именем name, но описание его как Person вернет эту возможность обратно.

Решение 2. Используйте более точное определение

type Require<T, K extends keyof T> = T & {
  [P in K]-?: T[P]
};

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

let person: Require<Person, 'name'> = getPerson();
let name1:string = person.name;

Решение 3: перепроектируйте ваш интерфейс

Форма, в которой все свойства являются необязательными, называется слабым типом и обычно является индикатором плохого дизайна. Если бы мы должны были сделать name требуемого свойства, ваша проблема уходит.

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

Ответ 6

Была такая же проблема.

Я обнаружил, что реакции-скрипты добавляют "strict": true к tsconfig.json.

После того, как я удалил это все прекрасно работает.

редактировать

Необходимо предупредить, что изменение этого свойства означает, что вы:

больше не получать предупреждения о возможных ошибках во время выполнения.

как было отмечено PaulG в комментариях! Спасибо :)

Используйте "strict": false только если вы полностью понимаете, на что это влияет!