Ray Booysen
Ray Booysen

Reputation: 30021

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

interface Foo {
  name: string;
}

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

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?

Upvotes: 357

Views: 798963

Answers (25)

DiaMaBo
DiaMaBo

Reputation: 2287

I had same issue and got it fixed with the below

 import { AgGridReact } from 'ag-grid-react';  

 const gridRef = useRef<AgGridReact>(null);

Upvotes: 0

dmbaughman
dmbaughman

Reputation: 608

Another reason this error can occur is if a function incorrectly returns different types based on some condition. For example:

if (!items.length) {
  return []
}

return { data: items }

I came across this issue when refactoring a function to return an object instead of an array, but I forgot to update the return value inside the if statement.

Correcting the issue looked like this:

if (!items.length) {
  return { data: [] }
}

return { data: items }

Upvotes: 0

crystal
crystal

Reputation: 241

For typescript developer using React... if you use React.useRef() hook Instead of pre-assign null, declare and use variable type any.

Example:

const initialRef: any = null;
const ref = React.useRef(initialRef);

Upvotes: 12

Luca Rosato
Luca Rosato

Reputation: 139

In React, If you use the UseState in this way, you shouldn't have a problem

const [data, setData] = useState<any>([]);

In the case of Javascript it works directly because all data types are Any by default, and this is not the case in Typescript, so you have to let the language know :)

Upvotes: 5

Matthabbey
Matthabbey

Reputation: 31

With React, you can type it as:

const [data, setData] = useState<Array>([]);

Upvotes: 1

Philipp Galliker
Philipp Galliker

Reputation: 49

This example worked for me. Here we are using a simple custom type object (product):

export interface ProductType {
    id: number;
    name: string;
}

export const Product: FC = () => {
    const [products, setProducts] = useState<ProductType[]>([]);

Upvotes: 0

Bulbul Sarker
Bulbul Sarker

Reputation: 102

When showing Property 'id' does not exist on type 'never'. message

selectedMinistryDivision(selectedId) {          
        for( let i = 0; i < this.ministryDivisions.length; i++) {
            if (selectedId == this.ministryDivisions[i].id) {
                return this.ministryDivisions[i];
            }
        }
    }

Solved my problem
selectedMinistryDivision(selectedId) {          
        for( let i = 0; i < this.ministryDivisions.length; i++) {
            if (selectedId == this.ministryDivisions[i]['id']) {
                return this.ministryDivisions[i];
            }
        }
    }

I have changed from this.ministryDivisions[i].id to this.ministryDivisions[i]['id']

Upvotes: 0

KushalSeth
KushalSeth

Reputation: 4649

For typescript with vue, if you want to assign a string and null value to a variable then use like this in data field: employeeType: "" || null later you can assign null or string to employeeType variable

export default defineComponent({
 data() {
    return {
        employeeType: "" || null,
    }
.........
})

Upvotes: 1

fruitloaf
fruitloaf

Reputation: 2892

My issue disappeared when I DESTRUCTURED my .MAP.

ERROR - Property 'loanId' does not exist on type 'never':

    {data?.map((el) => {
        return (
            <div key={el.loanId + el.transactionDate}>{JSON.stringify(el)}</div>
        );
    })}

NO ERROR - DESTRUCTURED:

    {data?.map((el) => {
        const { loanId, transactionDate } = el;

        return <div key={loanId + transactionDate}>{JSON.stringify(el)}</div>;
    })}

Upvotes: 0

blue-hope
blue-hope

Reputation: 3259

If you write the component as React.FC, and use useState(), you can write it like this:

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

Upvotes: 244

Nivethan
Nivethan

Reputation: 3609

if you're using React useRef hook with TypeScript, instead of using any you can do the following.

const ref = useRef<HTMLInputElement>(null);

Upvotes: 79

sushmitha reddy
sushmitha reddy

Reputation: 131

Sometimes the value could be empty initially. In that case you might want say example

let val = data.notificationId --> here it will throw an error. So we could simply write let val = data && data.notificationId

Upvotes: 0

Oranit Dar
Oranit Dar

Reputation: 1725

It happened to me when I forgot to define a type for the variable.

Upvotes: 3

Ahmed Meshaal
Ahmed Meshaal

Reputation: 119

In your component.ts file just declare the array as the following

public arrayName = ([] as any[]);

that's worked with me for Angular

Upvotes: 5

Rawand Deheliah
Rawand Deheliah

Reputation: 1582

in useState if u've never declared the type :

it assumes it is type is never so it shows this error :"Property does not exist on type 'never'"

you can type it as :

const [datalist, setDataList] = useState<Array<Object>>([]);

Upvotes: 1

Kia Kaha
Kia Kaha

Reputation: 1781

I've came across the issue with the following expression:

const node = item ? <a href={item.link}>{item.name}</a> : item.name

And the else part item.name said Property 'name' does not exist on type 'never'.

Well this is because if there is nothing inside the item object - there can't be a name property as well.

So this warning happens when you declare something basically impossible (that's why it's never)

Upvotes: 0

Lucas Gabriel
Lucas Gabriel

Reputation: 428

For me the following code is working:

const [disc, setDisc] = useState<any[]>([]);

What I've seen this far is the following: When you don't specify the type you are passing to the useState() it inferes it is type never. By make it use the any[] you are able to pass the data when it is requested.

Upvotes: 11

Ashu Sahu
Ashu Sahu

Reputation: 601

I was having problems with ? and !

This piece worked for me.

if (ref != null){
    if (ref.current != null)
        ref.current.appendChild(child);
}

Upvotes: 0

Eric Grotke
Eric Grotke

Reputation: 5125

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

e.g.:

obj.name -> obj['name']

Upvotes: 178

Kazeem Quadri
Kazeem Quadri

Reputation: 265

In my own case when I was initiating the array. I used:

selectedActors: any = [];

So it makes it "dynamic" at first

Upvotes: 12

Kiril Dobrev
Kiril Dobrev

Reputation: 851

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;

Upvotes: 1

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[];

Upvotes: 0

Ericgit
Ericgit

Reputation: 7063

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}
    ....
  />

Upvotes: 9

Nitzan Tomer
Nitzan Tomer

Reputation: 164139

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
}

Upvotes: 26

Saravana
Saravana

Reputation: 40584

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

Upvotes: 147

Related Questions