Design Meeting Notes, 2026-08-27

Aperta
#64,113 6 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
25/100
Tipo di issue
Documentazione
Chiarezza
Da chiarire
Stato di attività
Ferma
Stack tecnologico
typescript

Direzione di ricerca

Inizia leggendo le note della riunione e la PR #63926 collegata, concentrandoti sui tipi negati, sul restringimento del flusso di controllo, sugli alias e sulle proprietà opzionali. Le note contengono questioni di progettazione aperte, ma non indicano file, test, punti di ingresso o criteri di completamento; quindi, prima dell’implementazione, sarebbero necessarie ulteriori discussioni e la definizione dell’ambito.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Design Notes

Negated Types (not T)

https://github.com/microsoft/TypeScript/pull/63926

  • If you think about a venn diagram of A and B overlapping where A & B is the overlap, not A is all the area outside of A, not (A & B) is the inverse color of that original overlap.
  • Fresh object types are closed -
  • Talked about this before, have a feeling it's more relevant today.
  • Like what?
    • Something like a --noUnusedReturnedValues

      • Don't want to forget

      • People use void, but this accepts Promises that need to be awaited.

      • Can have an ignore to help here.

        function ignore(value: not PromiseLike<unknown>): void {}
        
    • `foo${string & not "reserved-key"}`

      • Record<`on${string & not keyof EventNames}`, unknown>
    • Can also do narrowing for carve outs of infinite sets.

      function divide(a: number, b: number & not 0): number {
          return a / b;
      }
      
      function doStuff(someValue: number) {
          if (someValue !== 0) {
              divide(10, x); // Okay
      
              // (come back to this below)
              const x = someValue;
              divide(10, x); // ...
          }
          else {
              divide(10, someValue); // Should error!
          }
      }
      
      • Okay, but how does that work with aliases
        • Currently an alias loses that information.
        • That is super surprising.
  • What are the old issues that this avoids?
    • We had a prototype that swapped out our fact-tracking system in control flow analysis and replaced it with negated type tracking.
    • But this was computationally intensive.
    • This PR introduces negations only for specific types of control flow narrowing in the false branch where we needed to track that info.
      • Only requests negation when a use-site of a binding needs negation.
      • Done based on the contextual type at that use-site.
      • We actually have similar logic here for when we narrow generic parameters in the body of a function!
        • Very similar precedent here.
  • Do you want the most precise type to be inferred
    • e.g. type narrowing conditionals (come back to this?)
    • We also infer type predicates for you now.
  • Negated types seem useful over the set of primitives, and often works well enough in the object hierarchy, but doesn't really make sense to have a provable negated object type.
    • An object doesn't necessarily exclude a Promise or a Function.
    • But all sorts of checks like this are all heuristics-based.
  • Could have a switch to check for negations?
    • But is this a strictness thing?
    • Feels like no - weird.
  • Does this feel consistent?
    • Should do this stuff everywhere.
    • But if you have a switch case with 200 cases, you'll get 200 nots in the default, whether you cared or not. This PR avoids that unless you actually need the negation.
  • Let's come back to use-cases.
    • not Promise
    • Control flow issues.
  • With this PR, it is very nice that it's both faster and that you don't see the nots in hover unless you need.
  • We do want to experiment a bit more with decomposing existing primitives here. There are some unknown unknowns here.
    • Is object equivalent to {} & not number & not string & not boolean & not symbol?
    • Is {} equivalent to not null & not undefined?
    • Maybe Extract and Exclude can be defined in this way?
      • Or rather, have the compiler produce intersections of negations wherever we otherwise produce these.
        • Aside: added a specific mechanism for reducing intersections in the presence of negations.
  • What does negation mean in the presence of optional properties?
    • not { optionalProp?: Type }
    • Out of time!
Lingua principale
Go
Stelle
111k
Fork
14.4k
Merge medio
1g 19h
PR unite (30g)
117

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/TypeScript

Tutte le issue di microsoft/TypeScript

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.