Skip to content

Type guards in array find #38945

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

Closed
jer-sen opened this issue Jun 5, 2020 · 4 comments
Closed

Type guards in array find #38945

jer-sen opened this issue Jun 5, 2020 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@jer-sen
Copy link

jer-sen commented Jun 5, 2020

TypeScript Version: 3.9.2

Search Terms:

Expected behavior: No error

Actual behavior: Error Type 'string | null | undefined' is not assignable to type 'string | undefined'. Typescript doesn't take into account the type guard in find arrow function.

Related Issues:

Code

const res: string | undefined = ["a", null].find((v) => v !== null);
Output
"use strict";
const res = ["a", null].find((v) => v !== null);
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

@MartinJohns
Copy link
Contributor

(v) => v !== null is not a type guard. It's a function that returns boolean. A type could would return v is string.

You can fix it by adding a type annotation to make it a type guard: find((v): v is string => v !== null)

Alternative just add a comfort function:

function isNotNull<T>(value: T | null): value is T { return value !== null; }

find(isNotNull)

Also your playground link does not work.

@jer-sen
Copy link
Author

jer-sen commented Jun 5, 2020

v !== null is a type guard, no ?
Typescript should do the same assumption on find result than inside a if (res !== null) { ... }
Ideally a developer should not have to do anything special for this code to work. Don't you agree ?

But your code works fine thanks !

As for the playground link I used the "Export->Report GitHub issue on TypeScript" menu of typescript Playground...

@Barbiero
Copy link

Barbiero commented Jun 5, 2020

v !== null is a type guard, no ?
Typescript should do the same assumption on find result than inside a if (res !== null) { ... }
Ideally a developer should not have to do anything special for this code to work. Don't you agree ?

But your code works fine thanks !

As for the playground link I used the "Export->Report GitHub issue on TypeScript" menu of typescript Playground...

no, v !== null is an expression which typescript can use to infer a more restricted type, but it's not an actual type guard.

The problem is that typescript can't really return guard-like expressions from a function without explicitly stating that the function is a guard. I've wrote the #37868 issue in an attempt to address that situation; hopefully someone more knowledgable than me can work that into the language.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jun 5, 2020
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants