microsoft / microsoft/TypeScript
Allow composite values to be used in type predicates
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
Allow composite values to be used in type predicates
đ Search Terms
Is, composite type, complex type, composite value, complex value, type predicate, type guard
â Viability Checklist
My suggestion meets these guidelines:
- This wouldnât be a breaking change in existing TypeScript/JavaScript code
- This wouldnât change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isnât a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScriptâs Design Goals.
â Suggestion
Type predicates allow you to define functions that can tell the TypeScript compiler if a parameter is of a certain type.
I suggest that this be extended to allow type predicates to narrow the type of composite objects involving parameters.
That is, the left-hand-side of is types should be allowed to include object literals.
đ Example
Say you have a type that involves a subset of another type:
type MyType = {property1: "static text", property2: "Hello" | "World"};
A type predicate for this would always require passing in the property1 property, even though itâs unnecessary.
Now, you can create a type predicate that only takes the value of property2, but still gurantees the result type:
function foo(text: string): {property1: "static text", property2: text} is MyType {
return ["Hello", "World"].includes(text);
};
Iâve run into the problem of being unable to do this while developing my website.
I had a tagged union:
type A = {t: "A", value: "X" | "Y"};
type B = {t: "B", value: string};
type U = A | B;
And I wanted to get a value of type A from user input, but default back to a B type if the value wasnât
To do this, I hoped to be able to do this:
function zit(x: string): {t: "A", value: x} is A {
return ["X", "Y"].includes(x);
};
function gob(x: string): U {
return zit(x) ? {t: "A", value: x} : {t: "B", value: x};
};
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up â it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No files, tests, or entry points are named. Start by reviewing the issueâs type-predicate examples and the compilerâs existing type-guard behavior; the change would be complete when composite object types are accepted in predicates and the shown narrowing scenarios work without changing emitted JavaScript.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100