TypeScrip: Oh, dieses lustige Typensystem

Hallo, mein Name ist Dmitry Karlovsky und kürzlich habe ich zusammen mit Artur Mukminov einen Workshop abgehalten , in dem ich gezeigt habe, wie man komplexe Typofunktionen durch Testen entwickelt . Dies sind 2 Stunden harte Programmierung. Nehmen Sie als Teaser eine Analyse der Kuriositäten des Typoskript-Typsystems auf.













Beziehungen sind schwer



Es ist sehr einfach zu überprüfen, ob ein Typ ein Subtyp eines anderen ist, indem man typoternarisch verwendet:







type IsAExtendsB = A extends B ? true : false
      
      





Classify, 2 4 :







  • [ A, '<:', B ]



    — A B.
  • [ A, ':>', B ]



    — B A.
  • [ A, '==', B ]



    — ( ).
  • [ A, '!=', B ]



    — .


, Equal Assert, , , . Assert , .







! ..



Object



object



— , , :







type boolean_is_Object = Assert<
    boolean extends Object ? true : false,
    true
>

type boolean_is_not_object = Assert<
    boolean extends object ? true : false,
    false
>
      
      





, , , :







type Object_vs_object = Assert<
    Classify< Object, object >,
    [ Object, '==', object ]
>
      
      





: (, boolean



) (, Object



), — (, object



), — .







, . Object



, object



.









, , — , :







type boolean_is_true_or_false = Assert<
    boolean,
    true | false
>
      
      





:







enum FL4 { Absurd, False, True, Unknown }

type FL4_is_union = Assert<
    FL4,
    | FL4.Absurd | FL4.False | FL4.True | FL4.Unknown
>
      
      





( ):







type Absurd_is_number = Assert<
    Classify< FL4.Absurd, number >,
    [ FL4.Absurd, '==', number ]
>
      
      





:







type Absurd_is_never_wtf = Assert<
    Classify< FL4.Absurd, 0 >,
    [ never, '<:', 0 ]
>
      
      





, , ? , !







type One_is_never_wtf = Assert<
    Classify< FL4.Absurd, 1 >,
    [ FL4.Absurd, ':>', never ]
>
      
      





, , !







, — , :







enum FL3 { Absurd, False, True }

type Absurd_is_not_Absurd = Assert<
    Equal< FL3.Absurd, FL4.Absurd > | false,
    false
>
      
      





, . , , , :







enum HappyDebugging {
    False = "True", 
    True = "False",
}

type True_extends_string = Assert<
    Classify< HappyDebugging.True, string >,
    [ HappyDebugging.True, '<:', string ]
>
      
      





, number



, string



.









, :







  • never



    . , .
  • unknown



    — . . unknown



    .


Aber was droht neben ihnen? Ja das ist es any



!
Einerseits ist es vollständig austauschbar mit unknown



:







type unknown_is_any = Assert<
    unknown,
    any
>
      
      





Aber andererseits ist es wie Schrödingers Katze ein Subtyp never



(und folglich jede andere Art von Do unknown



) und nicht gleichzeitig so:







type any_maybe_extends_never = Assert<
    any extends never ? true : false,
    true | false
>
      
      





Kurz gesagt, es any



bricht den Boden in jeder Hinsicht. Das Schicksal derer, die ihm von Angesicht zu Angesicht begegnen, ist schwer ...













Der gesamte Code aus dem Artikel.







Viel Spaß beim Debuggen!














All Articles