Typescript: Type 'string | undefined' is not assignable to type 'string'

typescript type vs interface
typescript type keyword
typescript type check
typescript function type
typescript object type
typescript interface
typescript type assertion
typescript record

When I make any property of an interface optional, I an error like following while assigning its member to some other variable

TS2322: Type 'string | undefined' is not assignable to type 'string'.   Type 'undefined' is not assignable to type '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 

How do I get around this error?

You can now use the non-null assertion operator that is here exactly for your use case.

It tells TypeScript that even though something looks like it could be null, it can trust you that it's not:

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

Handbook - Basic Types, In TypeScript, we support much the same types as you would expect in JavaScript, with a convenient enumeration type thrown in to help things along. Boolean. Basic Types Introduction #. For programs to be useful, we need to be able to work with some of the simplest units of data: numbers, Boolean #. The most basic datatype is the simple true/false value, which JavaScript and TypeScript call a boolean value. Number #. As in JavaScript, all numbers in

To avoid the compilation error I used

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

And then validate the empty string.

By Example · TypeScript, Type compatibility in TypeScript is based on structural subtyping. Structural typing is a way of relating types based solely on their members. This is in contrast​  Type annotations can be exported to a separate declarations file to make type information available for TypeScript scripts using types already compiled into JavaScript. Annotations can be declared for an existing JavaScript library, as has been done for Node.js and jQuery .

I know this is kinda late answer but another way besides yannick's answer https://stackoverflow.com/a/57062363/6603342 to use ! is to cast it as string thus telling TypeScript i am sure this is a string thus converting

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

to

let name1:string = person.name as string;

This will make the error go away but if by any chance this is not a string you will get a run-time error which is one of the reassons we are using TypeScript to ensure that the type matches and avoid such errors at compile time.

Type Compatibility · TypeScript, In addition to describing an object with properties, interfaces are also capable of describing function types. To describe a function type with an interface, we give  TypeScript provides several utility types to facilitate common type transformations. These utilities are available globally. Partial<T> Constructs a type with all properties of T set to optional. This utility will return a type that represents all subsets of a given type. Example

As of TypeScript 3.7 you can use nullish coalescing operator ??. You can think of this feature as a way to "fall back" to a default value when dealing with null or undefined

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

The ?? operator can replace uses of || when trying to use a default value and can be used when dealing with booleans, numbers, etc. where || cannot be used.

Handbook - Interfaces, TypeScript provides several utility types to facilitate common type transformations​. These utilities are available globally. Partial<T>. Constructs a type with all  As per the TypeScript Language Specification: Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind of type, including primitive, union, and intersection types.

try to find out what the actual value is beforehand. If person has a valid name, assign it to name1, else assign undefined.

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

Handbook - Utility Types, TypeScript extends JavaScript by adding types to the language. TypeScript speeds up your development experience by catching errors and providing fixes  Type Search. Powered by DefinitelyTyped and types-publisherDefinitelyTyped and types-publisher

TypeScript: Typed JavaScript at Any Scale., Here, we will use a type variable, a special kind of variable that works on types rather than values. ts. function identity<T>(arg: T): T { return  With TypeScript being an extension of JavaScript, the language naturally supports let and const. Here we’ll elaborate more on these new declarations and why they’re preferable to var. If you’ve used JavaScript offhandedly, the next section might be a good way to refresh your memory.

Handbook - Generics, Type aliases don't create a new name — for instance, error messages won't use the alias name.” that's incorrect ! (since TypeScript 2.1). Let's  Browse & Discover Thousands of Computers & Internet Book Titles, for Less.

Interface vs Type alias in TypeScript 2.7 - Martin Hochel, TypeScript - Types - The Type System represents the different types of values supported by the language. The Type System checks the validity of the supplied 

Comments
  • That's exactly what I was looking for!
  • Until ESLint does not restrict usage of non-null assertion operator :)
  • I'm shocked such a thing needs to exist. 🤯
  • @GONeale there are many cases where the transpiler can't figure out on its own that a value cannot be null. One example is a value set e.g. by Angular, and Angular has its own way of guaranteeing that the value cannot be null.
  • This is terrible advice! Instead, help the compiler figuring it out. Add a check before accessing the property, where you either throw or return if the name is not set.
  • What if it isn't a string but object?
  • If it an object then instead of ' ' it will be {}
  • hmmm. That will be too verbose if I want to do multiple assignments. Is there a way to turn off this particular warning?
  • unfortunately not except you make name mandatory by removing the question mark.
  • PS: Which version of TypeScript do you use? I use 3.2.4 and do not run into this Message. In my test class the code perectly compiles.
  • same version. I get this error in webstorm but not in vscode
  • That is strange, because I use IntelliJ which is supposed to be similar to WebStorm when it comes to application of TS-rules?!
  • This may 'work'. But it only works in the sense that you're not being warned about potential run time errors anymore. I'd encourage research on what the strict checking in Typescript does : medium.com/webhint/going-strict-with-typescript-be3f3f7e3295
  • I should mention that the OP asked, "How do I get around this error?" not, "How do I fix this issue?"
  • Simply adding name:string = undefined (as recommended by packages like json2typescript) will throw error 2322 unless you turn strict off, which is what most people will need to do. This accepted answer is clear, correct, and deserves many more votes.