question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow inline type predicates

See original GitHub issue

From #5731

if (<foo is Element>(foo.nodeType === 1)) { 
    // Assume foo is Element here
}

A proposal from @sandersn: https://github.com/Microsoft/TypeScript/issues/5731#issuecomment-162586789

Type Predicate Expressions

A type predicate expression allows you to narrow a union type with a single expression. The syntax is

<variable is type> boolean-expression

When the expression is used in a conditional context, the true branch of the conditional narrows variable to type, while the false branch narrows variable by removing type.

The type predicate expression is of type Boolean, with apparent type of type predicate. The right hand side must be an expression of type Boolean. The left hand side’s variable must be a name bound in the current scope. The left hand side’s type must be a name bound in the current scope.

Open questions

  1. How does variable capture work? Can a type predicate expression be returned from a function and used to narrow a variable that’s no longer in scope? This could be defined to cause an error, but that restriction is neither obvious nor easy to use.
  2. Why reuse the type assertion syntax? The type of the right expression is checked to be Boolean, unlike assertions, and the resulting type is still Boolean, also unlike assertions.

Issue Analytics

  • State:open
  • Created 8 years ago
  • Reactions:12
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
pushkinecommented, Nov 23, 2022

Here’s a workaround that gets removed by bundlers

const Narrow = <T>(v): v is T => true;

if (foo.nodeType === 1 && Narrow<Element>(foo)) {
}

(edit 2022) Here’s another workaround that works as a statement (= works in switch blocks)

function Narrow<T extends R, R = unknown>(value: R): asserts value is T {}

switch (foo.nodeType) {
	case 1: {
		foo; // any
		Narrow<Element>(foo);
		foo; // Element
	}
}

Playground Link

2reactions
ethanresnickcommented, Nov 21, 2022

You could also imagine doing this as the annotation for a variable holding the predicate’s result, i.e.:

declare const foo: Node;
const isElement: foo is Element = foo.nodeType === 1;

if (isElement) {
    // Assume foo is Element here
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Type predicates in TypeScript - Stack Overflow
I know that I can cast the type using as string or make use of the type predicates and use is string type...
Read more >
Documentation - Advanced Types - TypeScript
Using type predicates​​ A predicate takes the form parameterName is Type , where parameterName must be the name of a parameter from the...
Read more >
Narrowing in TypeScript with Type Predicates and ... - Felt
Discriminated unions are the natural fit for working with unions in TypeScript. Here's why I advise them over inline checks and type predicates....
Read more >
SQL Server 2016 : Implement Row Level Security using ...
A Predicate function is an Inline Table Valued function, which checks whether the user who is executing a particular query on the table...
Read more >
TypeScript Type Guards and Type Predicates
Union types enable us to accept parameters of multiple, different types. Provide either type x or y . Sometimes, these types aren't 100% ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found