Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegExp.test() fails to build in strict mode with undefined or null input #20501

Closed
styfle opened this issue Dec 6, 2017 · 2 comments
Closed

Comments

@styfle
Copy link
Contributor

styfle commented Dec 6, 2017

TypeScript Version: 2.7.0-dev.20171206

Code

function getDevice() {
    if (window && window.screen) {
        const w = window.screen.width;
        if (w > 1000) {
            return 'desktop';
        } else if (w > 800) {
            return 'tablet';
        } else {
            return 'mobile';
        }
    }
    return undefined;
}

const device = getDevice();
const isMobile = /mobile|tablet/.test(device);

Expected behavior:

Should compile in strict mode.

Actual behavior:

Does not compile in strict mode.

Type 'undefined' is not assignable to type 'string'.

Workaround

The workaround is to check if undefined and return a string before calling regexp.test(). For example:

const device = getDevice() || '';
const isMobile = /mobile|tablet/.test(device);

Solution

I believe the type definition for RegExp.test() should be the following

test(string: string | undefined | null): boolean;

The reason being, that test() seem to return false in the case of null or undefined.
MDN does not mention that it throws.

@ghost
Copy link

ghost commented Dec 6, 2017

Seems like a duplicate of #4002 -- the function is intended to be used with strings and will convert any other input to a string. It won't throw an error but probably isn't doing what you intended. (/undefined/.test(undefined) is true!)

@styfle
Copy link
Contributor Author

styfle commented Dec 6, 2017

@andy-ms That is very interesting. I didn't consider the case of /undefined/.test(undefined) because my example is clearly not testing against /undefined/ so there is no unintended bug.

I'll leave the reader with this real world example that is deceiving at first glance:

const reg = /(def|func)/;
console.log(reg.test('func')); // true, expected
console.log(reg.test('def')); // true, expected
console.log(reg.test('nope')); // false, expected
console.log(reg.test(undefined)); // true!, WHAAT??

I suppose TypeScript is right to complain in order to catch these odd corner cases.

@styfle styfle closed this as completed Dec 6, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant