When working with TypeScript from version TS 3.1.6 onwards (the oldest version I tested), there is no requirement to include an explicit exhaustiveness check like:
const _exhaustivenessCheck: never = unitOfTime;
In situations where the compiler recognizes final switch
statements as exhaustive within a function. Therefore, an error will not be generated in scenarios such as this:
function waterFrequencyToMilliseconds(number: number, unitOfTime: UnitOfTime): number {
switch (unitOfTime) {
case 'days': {
return number * ONE_DAY;
}
case 'weeks': {
return number * ONE_WEEK;
}
}
}
However, if your switch
statement lacks exhaustiveness, an error will occur:
function oopsWaterFrequencyToMillis(number: number, unitOfTime: UnitOfTime): number {
// error! function lacks ending return statement --------------------------> ~~~~~~
switch (unitOfTime) {
case 'days': {
return number * ONE_DAY;
}
}
}
Hence, for the specific code example provided above, the exhaustiveness check can be omitted.
Starting from TypeScript 3.7, the language offers improved support for detecting unreachable code through control-flow analysis. This eliminates the need to explicitly throw
or return
within sections of code identified by the compiler as unreachable, such as after an exhaustive switch
statement. For more details, refer to this comment on the implementation's pull request.
Moreover, not only is an explicit exhaustiveness check unnecessary, but it will trigger an unreachability warning in TypeScript 3.7+:
function explicitExhaustiveCheck(number: number, unitOfTime: UnitOfTime): number {
switch (unitOfTime) {
case 'days': {
return number * ONE_DAY;
}
case 'weeks': {
return number * ONE_WEEK;
}
}
const _exhaustivenessCheck: never = unitOfTime; // error!
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//unreachable code detected.
}
Hence, it is advisable to remove such checks.
If you require compatibility with older TypeScript versions and possess sample code illustrating the necessity of an explicit exhaustiveness check, consider replacing the variable declaration with a specific return
statement like return assertNever(unitOfTime)
, wherein assertNever()
solely accepts arguments of type never
. This adjustment may satisfy linting requirements. However, without a reproducible instance of the issue mentioned, the answer provided addresses the query comprehensively.
Access the code on TypeScript Playground