Is there a better type than any for a boolean like function argument. The function itself will only check for falsy/truthy value. The type should indicate that it is only a switch and the developer does not have to convert any value to boolean.
If you try to compare the value of this type to another value an error will be shown. The only use is to compare if value is something or not.
Is there a better type than any for a boolean like function argument. The function itself will only check for falsy/truthy value. The type should indicate that it is only a switch and the developer does not have to convert any value to boolean.
If you try to compare the value of this type to another value an error will be shown. The only use is to compare if value is something or not.
Share Improve this question edited Feb 2 at 23:44 Nico Richter asked Feb 2 at 18:30 Nico RichterNico Richter 3791 silver badge10 bronze badges 10 | Show 5 more comments1 Answer
Reset to default 2There is no better type than the any
type or possibly the unknown
type or its near-equivalent {} | undefined | null
for this purpose. Every value in JavaScript is either truthy of falsy, so that means you want a type that accepts every possible value. That's any
, or unknown
.
Right now it's not possible to accurately write a type for just the falsy values. It's similar to type Falsy = false | 0 | "" | null | undefined | 0n | ""
, but there is no literal type for NaN
, so there's a hole in Falsy
that NaN
can slip through. A feature request at microsoft/TypeScript#28682 asks for a NaN
type, but it's unlikely to be implemented anytime soon.
Even worse, it is completely impossible to accurately write a type for just the truthy values. It's similar to type Truthy = true | number | string | bigint | object | symbol
, but there is no way to carve out the falsy number
s and string
s and bigint
s. That is, there's no negated types like not X
to let you do type subtraction. So there's a hole in Truthy
that 0
, and 0n
, and ""
can slip through. Oh, and NaN
slips through this one also. With negated types we could write (number & not 0)
and (string & not "")
. Or we might as well just write type Truthy = not Falsy
. But we can't. A feature request at microsoft/TypeScript#4196 asks for negated types, but it's not part of the language and again, unlikely to be implemented anytime soon.
If both of the above features were implemented, then you could write type Booleany = Truthy | Falsy
as the union of Truthy
and Falsy
.
But that still wouldn't give you the behavior you're apparently looking for. After all, the above Booleany
is still equivalent to any
or unknown
. You say you want to prevent someone from doing anything with a value b
of type Booleany
except for passing it directly to a function that accepts such a type like f(b)
, or possibly doing a truthiness check on it like if (b)
or if (!b)
. If someone does a test like typeof b === "string"
or b === b2
, you want to see a compiler error. That's not something TypeScript can ever do. TypeScript allows typeof
checks and equality checks on all values, whether there types are Booleany
or not.
It's possible that you might be able to use a linter like typescript-eslint, and write a custom rule that detects when values are of the Booleany
type and tries to enforce your restrictions. But that's out of scope of TypeScript and has nothing to do with the type system directly. And since Booleany
is equivalent to unknown
, it might be hard to write a linter rule that doesn't accidentally apply in unexpected places, or fail to apply in expected places.
The closest you could do in just TypeScript would be to come up with a "placeholder" type for Truthy
and Falsy
like type Truthy = true & {__placeholder: true}
and type Falsy = false & {__placeholder: true}
, using nominal-ish aliases, and then you've got type Booleany = Truthy | Falsy
. But now Booleany
doesn't accept any value at all, really. You'd need to map any value to Booleany
, like function toBooleany(x: any): Booleany { return !!x as any }
. But if you're going to convert values to a special type that has only two possible values, then... well, that type already exists. It's called boolean
: function toBoolean(x: any) { return !!x }
.
So I'd suggest that really what you want to do is convert your values to true boolean
s and then use them and get all the benefits of strong typing. That's going to be a lot easier and less prone to bugs than trying to fight the type system by promoting JavaScript's loose "truthy/falsy" concept to a first class type in TypeScript.
any
type? If so, that sounds like the most appropriate. – CPlus Commented Feb 2 at 18:530 <= x <= 1
with an unnormalisable prior probability distribution ofP(x) = 1/(x*(1-x))
. It is symmetric aboutx = 1/2
and represents the most uninformative state of knowledge about a binary decision prior to there being any data available. Somewhat old hat now but you might also want to investigatefuzzy logic
which once had a serious following back in the 1990's. – Martin Brown Commented Feb 2 at 20:25unknown
) – HairyHandKerchief23 Commented Feb 2 at 20:32any
" when you apparently are not placing any restriction on the value (because every value in JS is either truthy or falsy)? You could useunknown
but that's effectively the same when it comes to a function input. If you want some kind of documentation you can define an alias liketype Booleany = any
ortype Booleany = unknown
and then useBooleany
in your function, but it's not changing the types, just the names for the types. Please edit to clarify the use case and your requirements. – jcalz Commented Feb 2 at 20:50