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.

Suggestion: short-circuit type inference for ternary operators when both branches have the same type

See original GitHub issue

From https://github.com/squidfunk/typescript-issue-38339-repro (courtesy of @squidfunk)

TypeScript Version: 3.9.1-rc

Search Terms:

Subtype reduction, ternary

Code

import { JSX } from "preact"

type IntrinsicElements = JSX.IntrinsicElements[keyof JSX.IntrinsicElements]

export type IntrinsicElements2<
  T = IntrinsicElements
> = {
  [K in keyof T]: K extends "accept"
    ? T[K] | [string]
    : T[K]
}

export type IntrinsicElements3<
  T = IntrinsicElements2
> = {
  [K in keyof T]: K extends "class"
    ? T[K] | [boolean]
    : T[K]
}

export type IntrinsicElements4<
  T = IntrinsicElements3
> = {
  [K in keyof T]: K extends "id"
    ? T[K] | [number]
    : T[K]
}

export function foo(): IntrinsicElements4 | undefined {
  let t: IntrinsicElements4 | undefined
  // this takes 2 seconds to check
  return t
  // this takes 10 seconds to check
  // return true ? t : t
}

Expected behavior: return t and return true ? t : t check in a comparable amount of time

Actual behavior: the ternary is much slower

Playground Link: https://www.typescriptlang.org/play/?ts=Nightly#code/JYWwDg9gTgLgBAbzgKQMoA04F84DMoQhwBEYUApgIYDGMxAUPTAJ5jlwCSAdjFMFwGdg1AKIAbciHI8BcALwoMAOm69+Q0RKkyA2gGtyzCLkXoVPPoOHjJ0mAIC6jcgA9IsOCzacL661rsBACYAHno4OAAVeR81K01bGXoAPhiEcLgdAGk4fjgDIxNIhwAuOBzXGGkAE1liGmpyMDoMiIB+KOyHOAAfTIE4gHMnCIiyyK76LGc3aHgvdlVLDRttewBmMIjohSW-BLXglLSM7NyufMNjKNLyuEqauuoxSgEBBlG4Doms7r6dABGEAgEkoXBGo3Gk2m9Fc7nmrEWvniq0CABYtlEYnsUQEZOtjgp0hEznkCtdimUKi4qlxaiRgNUPqNvl1epkuABXEAA8hQCFjTq-KYzeF4TlcWjACAXXDAgAUAEoyjiVnj7Gj2RLquRcPxyNVEBkJPMVci1YkNVq6br9dUMgB6B0UGCcqAXeBOuAAMVeMAyLrdHqgnPYHXgZU9DrgqDEEAA7iKgA

Related Issues: #38339

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
ahejlsbergcommented, May 10, 2020

Also, the IntrinsicElementsX mapped types can be written more efficiently as:

type IntrinsicElements2 = IntrinsicElements |
  { [K in keyof IntrinsicElements]-?: K extends "accept" ? [string] : never };

type IntrinsicElements3 = IntrinsicElements2 |
  { [K in keyof IntrinsicElements]-?: K extends "class" ? [boolean] : never };

type IntrinsicElements4 = IntrinsicElements3 |
  { [K in keyof IntrinsicElements]-?: K extends "id" ? [number] : never };

This flattens the type into a union instead of stacking multiple mapped types on top of each other.

Even more efficient is to have a single type do the augmentation:

type IntrinsicElements4 = IntrinsicElements |
  { [K in keyof IntrinsicElements]-?:
    K extends "accept" ? [string] :
    K extends "class" ? [boolean] :
    K extends "id" ? [number] :
    never
  };
1reaction
amcaseycommented, May 12, 2020

@squidfunk We’ve been building popular OSS projects looking for perf issues, but it’s very valuable to have author input on intentions and expectations. Otherwise, it’s hard to for us to tell whether the performance we’re seeing is worse than it ought to be and whether the types can be changed without losing something important.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is it possible to infer the type of an if-then expression? : r ... - Reddit
Type inference would be easy if it were an if-then-else expression because then you can add a type constraint that says both branches...
Read more >
ternary operator ?: suggestion - Discussion - Swift Forums
In my mind, it makes sense to have both a heavier switch statement, (which might have many sub-statements in each branch), and also...
Read more >
Ternary operator in Java only evaluating one expression since ...
In a manner similar to the short-circuit operators, if one of the two right-hand expressions in a ternary operator performs a side effect,...
Read more >
Groovy Language Documentation
The ternary operator is also compatible with the Groovy truth, ... the Groovy type checker performs type inference whether this operator is present...
Read more >
December | 2006 - Panopticon Central
IIF, a True Ternary Operator and Backwards Compatibility ... inference algorithm–currently if a type parameter infers to two or more types, ...
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