Phil
Phil

Reputation: 173

Error: "Type '(num: number) => number' is not assignable to type 'number'.(2322)"

When I have a function like this, I get no complaints:

const roundToTwo = (num: number) => {
  return +(Math.round(+(num + "e+2")) + "e-2");
};

When I hover over the function name in VS Code, I can see that it's returning a number: const roundToTwo: (num: number) => number.

But when I try to define the return type like this:

const roundToTwo: number = (num: number) => {
  return +(Math.round(+(num + "e+2")) + "e-2");
};

I get this error:

Type '(num: number) => number' is not assignable to type 'number'.

Why is this or what am I doing wrong?

Upvotes: 2

Views: 4681

Answers (3)

Inigo
Inigo

Reputation: 15020

Since you're confused by both the syntax and semantics, I'm providing a detailed explanation.

roundToTwo is a function type, not a number

Given this defintion:

const roundToTwo = (num: number) => {
  return +(Math.round(+(num + "e+2")) + "e-2")
}

this is the actual (and correctly inferred) type of roundToTwo:

(num: number) => number

Why? Because roundToTwo is a function type, not a number. The type is inferred from the function expression being assigned to it. Remember, in Javascript, functions are first class objects. Likewise, in Typescript they are first class types.

But const roundToTwo: number gives it the type number

That is what you mistakenly did at the start of your new definition. You said, "roundToTwo is a number" and then you tried to assigned a function to it, getting an expected type error:

const roundToTwo: number = (num: number) => {
  return +(Math.round(+(num + "e+2")) + "e-2")
}

// compare the above to:
const roundToTwo: number = 2
const n: number = 2

There's no need to explicitly type it

It's completely unnecessary to explicitly type roundToTwo since you assigned it a function expression immediately, and the inferred type is what you want anyway. Just like you don't need to add : number to this declaration:

const max = 42  // same as "const max: number = 42"

If you just wanted to explicitly type the return value of the function expression

Place the :number after the parameter signature like so:

const roundToTwo = (num: number):number => {
  return +(Math.round(+(num + "e+2")) + "e-2")
}

If you wanted to explicitly type the roundToTwo variable

You have two options.

The inline syntax:

const roundToTwo: (num: number) => number = (num: number) => {
  return +(Math.round(+(num + "e+2")) + "e-2")
}

Using a type alias:

type numericFunction = (num: number) => number

const roundToTwo: numericFunction = (num: number) => {
  return +(Math.round(+(num + "e+2")) + "e-2")
}

The type alias is more readable especially for more complex function signatures, but more importantly it is very useful if you have to reference this function type elsewhere, e.g. as a function parameter:

function scaleArray(arr: number[], scaleFunc: numericFunction): number {
   
}

Upvotes: 2

Deepak
Deepak

Reputation: 2742

The error shown is self explanatory. The return type of roundToTwo is (num: number) => number and not just number. When you are already specifying a return type through the function indirectly (Typescript does it though), specifying a primitive directly is not right.

The right way:

const roundToTwo: (num: number) => number = function (num: number) {
  return +(Math.round(+(num + "e+2")) + "e-2");
};

Or simply leave it without specifying the type directly. Typescript anyways applies the type since the initialization takes place right at the time of declaration.

Upvotes: 1

Mohammed Al-Reai
Mohammed Al-Reai

Reputation: 2786

try like this shape

 type roundToTwo=(num:number)=>number
 
const roundToTwo :roundToTwo= (num:number)=> {
  return +(Math.round(+(num + "e+2")) + "e-2");
};

Upvotes: 0

Related Questions