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?
512 Answers
if you write Component as React.FC, and using useState(),
just write like this would be helpful:
const [arr, setArr] = useState<any[]>([]) 8Because 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.
Edit:
The issue in the updated example is actually an open issue with the compiler. See:
3I had the same error and replaced the dot notation with bracket notation to suppress it.
e.g.:
obj.name -> obj['name'] 2This 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 } 3if 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} .... /> 2In my own case when I was initiating the array. I used:
selectedActors: any = []; So it makes it "dynamic" at first
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.
1In 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; 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[]; I was having problems with ? and !
This piece worked for me.
if (ref != null){ if (ref.current != null) ref.current.appendChild(child); } 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)
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>>([]);