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

Design Meeting Notes, 9/27/2023 #55898

Closed
DanielRosenwasser opened this issue Sep 27, 2023 · 0 comments
Closed

Design Meeting Notes, 9/27/2023 #55898

DanielRosenwasser opened this issue Sep 27, 2023 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Sep 27, 2023

Relate Control Flow to Conditional Types in Return Types

#33912
(continued from #55754)

function createLabel<T extends string | number>(
    idOrName: T,
): T extends string ? { name: string } : { id: number } {
    if (typeof idOrName === "number") {
        return { id: idOrName };
    }
    return { name: idOrName };
}
  • Can't easily implement these functions because we'll error on the return statements.

    • Need a type assertion.
  • Conditional types are not exactly accurate in what they can model. Your runtime type might not align with your design-time type.

    function foo<T>(x: T): T extends number ? number : string; {
      if (typeof x === "number") return x;
      return "";
    }
    
    let x: unknown = 42;
    foo(x); // has type string?
    • unknown doesn't extend number, but it could actually be one!
  • Roughly, conditional types aren't safe when the false-most branch doesn't contain (isn't a supertype of) the types in true branches.

    • ...or the conditional type doesn't check directly against the constrained types in some way.
      • Saved by conditional type distribution (otherwise also has issues!)
    • Constructivist logic sure is annoying!
      • It is easy to get this wrong.
  • This is a problem because you need this to accurately describe what an if statement does.

  • Could say the result is effectively a union when the types are comparable? Or intersection is non-vacuous?

  • Another concept - some way to express negation of literals and primitives.

    • Cannot carve out the object hierarchy.
  • These two ideas feel a bit tied - usually you can't say anything conclusively about intersections of object types being vacuous. You can always create new types by intersecting. But you can make statements regarding primitives.

  • It's probably too late to change conditional types. But there's forms of conditional types that are safe. And you could perform the narrowing when you encounter those.

  • Is it worth pushing on this space?

    • Well, the extends in a conditional type doesn't directly correspond to what a function will actually do. So that's not safe either. You'd need some way to relay what expressions do in type space.
    • Also, people needing to write this stuff explicitly - it becomes a burden as well.
  • Does type argument inference throw a wrench in here?

    • Doesn't feel like it, but possibly.
  • Feel is "too complex" but we're possibly not coming at this with a solution-oriented approach.

    • Intentionally picked a bad example.
    • But there's a lot of road bumps towards a good solution. Needs negated types, and special form of conditional types, and more accurate predicate in conditional types, and...
  • Want to come back to this convo while showing off what's actually enabled by the current prototype.

Emitting an Ambiguity Error When Declaration Emit Will Differ

#55860

export const blah = Math.random() < 0.5 ? "foo" : "bar";
  • Variable is a literal union in the project, widened to string in declaration emit.
  • Destructuring, &&, ||, and ?? have some different paths.
  • Erroring seems like a reasonable short-term solution - but would like to reconsider another time in a way that doesn't error.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Sep 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

2 participants