How to allow a function return type undefined
Asked Answered
H

3

5

I think that typescript has many unobvious places, making it not strict and not correct.

I want use undefined as functions return type. Because in reality it is undefined, not void or some other fictional type. But when I write this:

function myFunction(): undefined {
    
}

it says "A function whose declared type is neither 'void' nor 'any' must return a value".

It must not. And everyone can verify this. I don't want to agree with "void is better, we decided that promise equal undefined" and so on. And don't want to write return undefined, if it is obvious and redundant.

How to make it work in this example? May be some flag exist or some "miracle comment instruction"?

Here is the use case, explaining why I want explicit undefined:

Wrong example with an issue

Correct example with a solution

Hallah answered 12/1, 2021 at 20:19 Comment(14)
This behaviour can be customized via the tsconfig.json file, by setting noImplicitReturns to false.Benefit
"And don't want to write return undefined". Is it acceptable to write return?Randarandal
If you don't have a return statement, then why do you want to annotate the return value with anything other than void? It's never going to change and doesn't seem to depend on what the function does.Napoleon
@Benefit tried this in ts playground, and nothing happends, error anyway - typescriptlang.org/play?#code/…Hallah
@NicholasTower no. Because it returns already by itself.Hallah
@Napoleon because it's type is undefined. And different situations are not about type, they are about situations.Hallah
That's the thing - it's misleading to add a type if it has no meaning. void perfectly encapsulates "This function doesn't return anything". Saying it returns undefined suggests that makes sense. Yet, if it does it because any function always implicitly returns that value and you never rely or influence it, then there really isn't any meaning to that. You're obscuring the fact that the return value shouldn't be relied on.Napoleon
@Napoleon There is an exact meaning for me. The undefined means undefined. Not any other meaning or type. And when I mean undefined, I don't want use meaning "nothing or void or promise or any". Everything in my code may rely on this return type. This does not mean that I have to write return undefined to allow this "reliance on". I want an exact contract, not "something in some situation".Hallah
Everything in my code may rely on this return type If it always returns undefined, what sort of code are you planning to write that will interact with the return value? Like are you going to write code like if (myFunction() === undefined)? If you're not going to interact with it, then void is the correct type. If you are... well, frankly, i don't know what use that is, so i'd still recommend void unless you have an example that demonstrates the point.Randarandal
Yet you're introducing "something in some situations". Claiming that a non-returning function actually produces undefined is different to something like Array#find where undefined is a valid value from its domain. You've introduced two different meanings for the value in your code. Whereas void means a single thing. You further lose semantincs for defining your interfaces.Napoleon
Most notably you often don't care what a callback produces, so void perfectly encapsulates that. Yet if you demand it to return undefined you lose the ability to pass something like x => array.push(x) as a callback and instead have to do x => { array.push() } due to the dual semantics of undefined you've introduced.Napoleon
@NicholasTower , @Napoleon , thank you for answers. I can't show all the situations here, where void is a big pain. It is a big conversation, not for comments. I understand that maybe everyone think another way and nobody want strict return type, and they want all that meanings and advantages of void.Hallah
I can't show all the situations here One is all i need. In any event, if you truly understand what void means, and you still have decided that undefined is better for your case, then you will need to have an explicit return statement. Leaving out a return statement when you've said you'll return something is a bug in most people's code, which is why typescript enforces it.Randarandal
@NicholasTower I updated the question to show the use caseHallah
L
8

You would like the compiler to accept that a function whose return type annotation includes undefined can implicitly return undefined when a code path does not have an explicit return statement. This is a reasonable thing to want but, as you noticed, the language does not currently have this feature as of TypeScript 4.1. There is an open feature request for this at microsoft/TypeScript#36288. If you'd like to increase the chances that this will happen, you might want to go there and give it a 👍 and perhaps even describe why your use case requires this or why your code would benefit from it.

Realistically, though, unless you can get a large number of other people to clamor for that issue, it doesn't look like any language maintainers consider it to be a high priority.

The workarounds are ones you presumably dislike, but here they are anyway. First, explicitly include a return statement (without or without undefined):

function myFunctionReturn(): undefined {
    return; // okay
}

Second, use one of the error-suppressing comments like //@ts-ignore or //@ts-expect-error:

//@ts-ignore
function myFunctionIgnore(): undefined {

}

There may be other ways to deal with it, but without a minimal reproducible example of your use cases that consume or use such undefined-returning functions, it's hard to know how to separate this from the void-returning functions you are objecting to.

Playground link to code

Leeke answered 12/1, 2021 at 21:24 Comment(1)
Thank you. It is great that not only me think so, but somebody else who opened that request :)Hallah
A
0

You may try the following:

  1. Define a type:
type nullable<T> = T | null | undefined
  1. Define the return type to be nullable<Type>, e.g.:
const getString = (test: string): nullable<string> => test || undefined
Aggarwal answered 15/1, 2022 at 17:20 Comment(1)
null and undefined are 2 different things, using them interchangeably might lead to a headacheCrab
N
-2

Here you have magic comment:

//@ts-expect-error
function myFunction():undefined {
    
}
Nocturne answered 12/1, 2021 at 20:32 Comment(6)
You should never use @ts-expect-error unless you actually need an error to be in your code, usually for testing purposesBlossom
@AlexChashin I m not claiming that it is the best solution. OP asks about flags/comments that might be used in such situations. If you read accepted answer , you will find ts-ignore and ts-expect-error. Also, I m not saying that it is safe. It is just a workaround.Nocturne
It appears that SO users don't like magic. Either that or there's no magic here.Crab
@Crab seems like that :DNocturne
I mean that's just wrong. If anything it should be @ts-ignore, because that one at least says what your intention is (which is to turn off the type checking on this line). Imagine they suddenly fixed #36288 and allowed empty returns like this. Your expect-error will suddenly fail.Tessler
@Tessler sure, yoy are rightNocturne

© 2022 - 2024 — McMap. All rights reserved.