I have this array type:
interface Details {
Name: string;
URL: string;
Year: number;
}
interface AppState {
data: Details[];
}
I am using D3 to create an x axis like this:
createChart = () => {
const { data } = this.state;
const width = 900,
height = 600;
// x-axis
const x = d3
.scaleLinear()
.domain([
d3.min(data, ({ Year }) => (Year ? Year - 1 : 0)), // ERROR
d3.max(data, ({ Year }) => (Year ? Year + 1 : 0)) // ERROR
])
.range([0, width]);
};
On the marked lines using d3.min
and d3.max
I get the following error:
Type 'number | undefined' is not assignable to type 'number | { valueOf(): number; }'. Type 'undefined' is not assignable to type 'number | { valueOf(): number; }'.
How do I make this work?
The "Type 'undefined' is not assignable to type" error occurs when a possibly undefined value is assigned to something that expects a different type. To solve the error, use the non-null assertion operator or a type guard to verify the value is of the specific type before the assignment.
The error "Argument of type is not assignable to parameter of type 'never'" occurs when we declare an empty array without explicitly typing it and attempt to add elements to it. To solve the error, explicitly type the empty array, e.g. const arr: string[] = []; .
The "Type 'string' is not assignable to type" TypeScript error occurs when we try to assign a value of type string to something that expects a different type, e.g. a more specific string literal type or an enum. To solve the error use a const or a type assertion. Here is the first example of how the error occurs.
The error "Argument of type string | undefined is not assignable to parameter of type string" occurs when a possibly undefined value is passed to a function that expects a string . To solve the error, use a type guard to verify the value is a string before passing it to the function.
The "Type 'number | undefined' is not assignable to type number" error occurs when a possibly undefined value is assigned to something that expects a number. To solve the error, use the non-null assertion operator or a type guard to verify the value is a number before the assignment.
But TypeScript keeps throwing: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. Type 'undefined' is not assignable to type 'number'. I already tried to wrap the call with an if statement checking if externalId && typeof externalId === 'number', but I can't make the error go away.
Argument of type 'IX' is not assignable to parameter of type 'Record<"a", number>'. Types of property 'a' are incompatible. Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'. (2345)
While working with Reactive forms in Angular, we may come across the error ‘FormGroup | undefined’ is not assignable to type ‘FormGroup’ or null is not assignable to type ‘FormGroup’. Reason for the Error message: TypeScript is moving towards Strict Null Check.
For your call to d3.min()
the compiler will use the following type definition:
export function min<T, U extends Numeric>(array: Iterable<T>, accessor: (datum: T, index: number, array: Iterable<T>) => U | undefined | null): U | undefined;
As you can see the function can return either U
—in your case the type of Details.Year
, i.e. number
— or undefined
. This, however, does not match the type definition for the .domain()
method which takes an array of either numbers or values coercible to numbers:
domain(domain: Array<number | { valueOf(): number }>): this;
This explains why you get the error. The same, obviously, holds true for d3.max()
.
Looking at the documentation the reasons for d3.min()
to return undefined
are rather limited:
If the iterable contains no comparable values, returns undefined.
Given your code you are guaranteed to not run into this issue. For that reason you can safely cast the return values of d3.min()
and d3.max()
to number
:
const x = d3
.scaleLinear()
.domain([
d3.min(data, ({ Year }) => (Year ? Year - 1 : 0)) as number, // cast to number
d3.max(data, ({ Year }) => (Year ? Year + 1 : 0)) as number // cast to number
])
.range([0, width]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With