lobati
lobati

Reputation: 10235

TypeScript: non-zero number

I'm trying to figure out if there is a way to set up a type in TypeScript that reflects a non-zero number:

type Task = { id: number };
const task: Task = { id: 5 };
const tasks: { [taskId: number]: Task } = { 5: task };

function getTask(taskId: number | undefined): Task | undefined {
    return taskId && tasks[taskId];
}

Playground here

In the above code, TypeScript complains that because taskId is a number, it could be 0, which is falsey, so the function would return 0 rather than a Task or undefined. Practically speaking, it is impossible for a task id to be 0. It will always be a positive integer, so that case is not an issue. Is there a way to declare the Task type to indicate to TypeScript that this number will never be falsey? I'd rather avoid extra conditional logic to convince TypeScript.

Upvotes: 2

Views: 2441

Answers (1)

Michael
Michael

Reputation: 2454

There's no way for typescript to guarantee that there will be a task for any possible taskId.

There are a few options here:

  • use the non null assertion operator to inform typescript that you know better and are sure the task will always exist
  • constrain the type to be the set of possible taskId by defining them as an enum or similar
  • check that the task exists and throw an exception if it is undefined

Assuming that your set of tasks is dynamic, I would personally go for the last option, eg:

function getTask(taskId: number): Task {
     const task = tasks[taskId]
     
     if(!task){ throw new Error(`task with id ${taskId} does not exist`) }

    return task
}

As this will give you a useful error if your invariant is violated.

Upvotes: 1

Related Questions