Home > front end >  Function lacks ending return statement and return type does not include 'undefined'. in Ty
Function lacks ending return statement and return type does not include 'undefined'. in Ty

Time:12-19

I am studying TS. I'm trying to make simple calculator. How can I make it this calculator without switch statement? If the if statement is used, an error occurs in return type.

Screenshot of code

type Command = 'add' | 'substract' | 'multiply' | 'divide' | 'remainder';
const calculate = function (command: Command, num1: number, num2: number): number {
  if (command === 'add') return num1   num2;
  if (command === 'substract') return num1 - num2;
  if (command === 'multiply') return num1 * num2;
  if (command === 'divide') return num1 / num2;
  if (command === 'remainder') return num1 % num2;

// switch (command) {
//  case 'add':
//      return num1   num2;
//  case 'substract':
//      return num1 - num2;
//  case 'multiply':
//      return num1 * num2;
//  case 'divide':
//      return num1 / num2;
//  case 'remainder':
//      return num1 % num2;
//  default:
//      throw Error('unknown command');
// }
};
console.log(calculate('add', 1, 3)); // 4
console.log(calculate('substract', 3, 1)); // 2
console.log(calculate('multiply', 4, 2)); // 8
console.log(calculate('divide', 4, 2)); // 2
console.log(calculate('remainder', 5, 2)); // 1

TypeScript Playground

CodePudding user response:

Typescript has a type checking paradigm as type inference and here it tries to find out what should happen for the return type if all your conditions won't match . You need to handle all return types, one of these solutions could be the bellow one:

type Command = 'add' | 'substract' | 'multiply' | 'divide' | 'remainder';
const calculate = function (command: Command, num1: number, num2: number): number | void {
  if (command === 'add') return num1   num2;
  if (command === 'substract') return num1 - num2;
  if (command === 'multiply') return num1 * num2;
  if (command === 'divide') return num1 / num2;
  if (command === 'remainder') return num1 % num2;

// switch (command) {
//  case 'add':
//      return num1   num2;
//  case 'substract':
//      return num1 - num2;
//  case 'multiply':
//      return num1 * num2;
//  case 'divide':
//      return num1 / num2;
//  case 'remainder':
//      return num1 % num2;
//  default:
//      throw Error('unknown command');
// }
};
console.log(calculate('add', 1, 3)); // 4
console.log(calculate('substract', 3, 1)); // 2
console.log(calculate('multiply', 4, 2)); // 8
console.log(calculate('divide', 4, 2)); // 2
console.log(calculate('remainder', 5, 2)); // 1
console.log(calculate("badcommand", 2, 4)) // this won't return any value just error or undefined

If you are trying to change the function implementation due to the error you can make all the calculation functions like:

type Calculation = (num1: number, num2: number) => number

const add: Calculation = (num1, num2) => {
    return num1   num2;
}

const substract: Calculation = (num1, num2) => {
    return num1 - num2;
}
// Others

CodePudding user response:

Here's one way to solve it:

type Command = 'add' | 'substract' | 'multiply' | 'divide' | 'remainder';

const calculate = function (command: Command, num1: number, num2: number): number {
  return {
    'add':       () => num1   num2,
    'substract': () => num1 - num2,
    'multiply':  () => num1 * num2,
    'divide':    () => num1 / num2,
    'remainder': () => num1 % num2,
  }[command]();
};

console.log(calculate('add', 1, 3)); // 4
console.log(calculate('substract', 3, 1)); // 2
console.log(calculate('multiply', 4, 2)); // 8
console.log(calculate('divide', 4, 2)); // 2
console.log(calculate('remainder', 5, 2)); // 1

Playground

CodePudding user response:

TypeScript narrowing is cool but I wouldn't advise you bet too much on it.

Instead you can use a refactoring technique called "Replace Conditional with Polymorphism" to get rid of the if statements. Like so:

class Command {
    #num1 = 0;
    #num2 = 0;

    constructor(num1: number, num2: number) {
        this.#num1 = num1; 
        this.#num2 = num2;
    }
    get num1() { return this.#num1; }
    get num2() { return this.#num2; }
    command() {}
}

class AddCmd extends Command { 
    command() {
        return this.num1   this.num2;
    }
}

class SubtractCmd extends Command { 
    command() {
        return this.num1 - this.num2;
    }
}

class MultiplyCmd extends Command { 
    command() {
        return this.num1 * this.num2;
    }
}

class DivideCmd extends Command { 
    command() {
        return this.num1 / this.num2;
    }
}

class RemainderCmd extends Command { 
    command() {
        return this.num1 % this.num2;
    }
}

console.log(new AddCmd(1, 3).command()); // 4
console.log(new SubtractCmd(3, 1).command()); // 2
console.log(new MultiplyCmd(4, 2).command()); // 8
console.log(new DivideCmd(4, 2).command()); // 2
console.log(new RemainderCmd(5, 2).command()); // 1

Think about how you can introduce typescript types to the above code.

  • Related