最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typescript - Type for falsy and truthy values - Stack Overflow

programmeradmin0浏览0评论

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
  • Does typescript have an any type? If so, that sounds like the most appropriate. – CPlus Commented Feb 2 at 18:53
  • Bayesians would probably go for 0 <= x <= 1 with an unnormalisable prior probability distribution of P(x) = 1/(x*(1-x)). It is symmetric about x = 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 investigate fuzzy logic which once had a serious following back in the 1990's. – Martin Brown Commented Feb 2 at 20:25
  • this is probably what you want (notice that arg has a type of unknown) – HairyHandKerchief23 Commented Feb 2 at 20:32
  • 1 Why do you want something "better than any" when you apparently are not placing any restriction on the value (because every value in JS is either truthy or falsy)? You could use unknown 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 like type Booleany = any or type Booleany = unknown and then use Booleany 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
  • You are right, thats more a documentation. The only restriction is that the value does not matter. So i.e. typeof checks or comparisons (except for truthy/falsy) are not useful. Its like a type with only two states and not like any which can hold any value. – Nico Richter Commented Feb 2 at 22:20
 |  Show 5 more comments

1 Answer 1

Reset to default 2

There 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 numbers and strings and bigints. 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 booleans 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.

发布评论

评论列表(0)

  1. 暂无评论