I had looked over some other issues that were similiar to this one, however some of them had talked about modifying the tsconfig.json and changing the compiler options to include
"strictNullChecks": true,
"noImplicitAny": false,
However, my code looks like this:
export interface DetailedRankings {
show_id: number;
name: string;
category: string;
episodes: number;
story?: number;
characters?: number;
overall?: number;
}
function handleInputChange(category: keyof DetailedRankings, event: string, index: number) {
const value_number: number = parseFloat(event);
let list: DetailedRankings[] = [...detailed_ranks];
let obj: DetailedRankings = list[index];
obj[category] = value_number <--- Having issue with this.
}
I am under the impression that the reason this issue is being caused is because I have string and number within the interface. I am just a bit lost on what is causing the issue of.
Type 'number' is not assignable to type 'never'.
CodePudding user response:
The issue is that typescript cannot guarentee that the value of obj[category]
is assignable number
so it says that obj[category]
is assignable never
as it's not assignable.
A little hack you could do is just convert obj
to be a type Record<string, number>
or Record<keyof DetailedRankings, number>
Like this for example:
function handleInputChange(category: keyof DetailedRankings, event: string, index: number) {
const value_number: number = parseFloat(event);
let list: DetailedRankings[] = [...detailed_ranks];
let obj: Record<keyof DetailedRankings, number> = list[index];
obj[category] = value_number
}
Obviously this has the drawback of not being a DetailedRankings type anymore...
I believe it's just a drawback of strict typescript. As a programmer you know only number
keys of category
are passed to your function but there's no way to tell typescript that in strict mode (as far as I know)
CodePudding user response:
The issue here is that you are not restricting your function to only take keys where the type is number
. This may lead to runtime errors. What is preventing me from calling the function like this?
handleInputChange("category", "0", 0)
Now obj["category"]
will have a number assigned to it which breaks your interface defintion. The error is warning you from this unsoundness.
You could compute all number
properties in a seperate type and use it as the argument type in your function.
type DetailedRankingsNumberProps = keyof {
[K in keyof DetailedRankings as DetailedRankings[K] extends number
? K
: never
]: K
}
function handleInputChange(
category: DetailedRankingsNumberProps,
event: string,
index: number
) {
const value_number: number = parseFloat(event);
let list: DetailedRankings[] = [];
let obj: DetailedRankings = list[index]
obj[category] = value_number // No error anymore
}
handleInputChange("category", "0", 0) // compile time error now