Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

strict-boolean-expressions: Add 'allow-null-union', 'allow-undefined-union', 'allow-string', and 'allow-number' options #2033

Merged
merged 4 commits into from Jan 19, 2017

Conversation

andy-hanson
Copy link
Contributor

PR checklist

  • Addresses an existing issue: #0000
  • New feature, bugfix, or enhancement
    • Includes tests
  • Documentation update
  • Enable CircleCI for your fork (https://circleci.com/add-projects)

What changes did you make?

Added new options to strict-boolean-expressions to make it not quite as strict.
TypeScript allows anything in an if-statement, so there's a lot of room in between that and requiring that everything be a boolean.

Is there anything you'd like reviewers to focus on?

This rule wouldn't allow you to use string | number as a condition even if both allow-string and allow-number are on. I think that's fine.
It will allow number | undefined if allow-undefined is on, since that contains undefined in the union. But it's probably dangerous if the user just wanted to test for undefined. Thoughts?

…union', 'allow-string', and 'allow-number' options
@andy-hanson
Copy link
Contributor Author

Added an allow-mix option to handle the case mentioned above. No more number | undefined without the option on.

@@ -178,6 +178,11 @@ export function isTypeFlagSet(type: ts.Type, flagToCheck: ts.TypeFlags): boolean
/* tslint:enable:no-bitwise */
}

/** Type predicate to test for a union type. */
export function isUnionType(type: ts.Type): type is ts.UnionType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't clutter utils with wrappers for isTypeFlagSet. I can imagine this getting out of control

enum: [OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_NUMBER],
},
minLength: 0,
maxLength: 4,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxLength: 5

declare function get<T>(): T;

if (get<string | number>()) {}
~~~~~~~~~~~~~~~~~~~~~~ [If statement condition may be falsy if it is 0. Expected a boolean, undefined-union, or string.]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is unclear. How about This type is not allowed in the 'if' condition because it could be a number. Allowed types are boolean, undefined-union, or string. You might have to modify it to make the string easier to generate

if (get<string>()) {}

if (get<boolean | string>()) {}
~~~~~~~~~~~~~~~~~~~~~~~ [If statement condition mixes multiple kinds of falsy values. Expected a boolean or string.]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`This type is not allowed in the 'if' condition because it unions one or more disallowed truthy/falsy types. Allowed types are boolean or string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed "one or more" to "more than one" since it allows having exactly one falsy type.

@andy-hanson andy-hanson force-pushed the less_strict_boolean_expressions branch from 5217471 to 5d41aa0 Compare January 19, 2017 01:43
@usuyama
Copy link
Contributor

usuyama commented Jan 19, 2017

I like the idea of adding more options to 'strict-boolean-expressions'. Thank you for working on this.

I haven't started yet, but I was planning to add a new option (ex. no-enum-boolean-coercion) to 'strict-boolean-expressions' because our team wants to enable the rule only for enum values first. It is risky because enum values start from 0 by default. On the other hand, we want to allow number-boolean-coercion if we're using enum as flags. (Ref: https://basarat.gitbooks.io/typescript/content/docs/enums.html#enums-as-flags )

Ref: #1555

Did you consider having options like:

  • no-string-boolean-coercion
  • no-number-boolean-coercion
  • no-undefined-boolean-coercion
    so that we can enable the rules step by step? For example, our team wants to check only enum-boolean-coercion first.

@andy-hanson
Copy link
Contributor Author

andy-hanson commented Jan 19, 2017

strict-boolean-expressions as it is already forbids everything, including enums, numbers, RegExps, etc. This PR adds flags to allow more. So a no-string-boolean-coercion flag would be unnecessary, since if you don't want strings, you can just not set the allow-string option.

So, if you want to be as permissive as possible, just set all the flags. This will still be less permissive than TypeScript as RegExp will be caught.

Adding an allow-flags-enum option might be doable, but it would be tricky to detect which ones are flags enums. We might consider an enum a flags enum if all of its members are either powers of two, or are unions of the other members.

@nchen63 nchen63 merged commit ec3df32 into palantir:master Jan 19, 2017
@nchen63
Copy link
Contributor

nchen63 commented Jan 19, 2017

nice, thanks @andy-hanson!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants