[typescript] 'Property does not exist on type 'never'

This is similar to #40796374 but that is around types, while I am using interfaces.

Given the code below:

_x000D_
_x000D_
interface Foo {_x000D_
  name: string;_x000D_
}_x000D_
_x000D_
function go() {_x000D_
  let instance: Foo | null = null;_x000D_
  let mutator = () => {_x000D_
   instance = {_x000D_
     name: 'string'_x000D_
   };  _x000D_
  };_x000D_
_x000D_
  mutator();_x000D_
_x000D_
  if (instance == null) {_x000D_
   console.log('Instance is null or undefined');_x000D_
  } else {_x000D_
   console.log(instance.name);_x000D_
  }_x000D_
}
_x000D_
_x000D_
_x000D_

I have an error saying 'Property 'name' does not exist on type 'never'.

I don't understand how instance could ever be a 'never'. Can anyone shed some light on this?

Thanks in advance.

This question is related to typescript

The answer is


Because you are assigning instance to null. The compiler infers that it can never be anything other than null. So it assumes that the else block should never be executed so instance is typed as never in the else block.

Now if you don't declare it as the literal value null, and get it by any other means (ex: let instance: Foo | null = getFoo();), you will see that instance will be null inside the if block and Foo inside the else block.

Never type documentation: https://www.typescriptlang.org/docs/handbook/basic-types.html#never

Edit:

The issue in the updated example is actually an open issue with the compiler. See:

https://github.com/Microsoft/TypeScript/issues/11498 https://github.com/Microsoft/TypeScript/issues/12176


In my case it was happening because I had not typed a variable.

So I created the Search interface

export interface Search {
  term: string;
  ...
}

I changed that

searchList = [];

for that and it worked

searchList: Search[];

In my case (I'm using typescript) I was trying to simulate response with fake data where the data is assigned later on. My first attempt was with:

let response = {status: 200, data: []};

and later, on the assignment of the fake data it starts complaining that it is not assignable to type 'never[]'. Then I defined the response like follows and it accepted it..

let dataArr: MyClass[] = [];
let response = {status: 200, data: dataArr};

and assigning of the fake data:

response.data = fakeData;

I had the same error and replaced the dot notation with bracket notation to suppress it.

e.g.: obj.name -> obj['name']


This seems to be similar to this issue: False "Property does not exist on type 'never'" when changing value inside callback with strictNullChecks, which is closed as a duplicate of this issue (discussion): Trade-offs in Control Flow Analysis.

That discussion is pretty long, if you can't find a good solution there you can try this:

if (instance == null) {
    console.log('Instance is null or undefined');
} else {
    console.log(instance!.name); // ok now
}

if you write Component as React.FC, and using useState(),

just write like this would be helpful:

const [arr, setArr] = useState<any[]>([])

if you're receiving the error in parameter, so keep any or any[] type of input like below

getOptionLabel={(option: any) => option!.name}
 <Autocomplete
    options={tests}
    getOptionLabel={(option: any) => option!.name}
    ....
  />