@@ -588,7 +588,9 @@ which produce aliases that have some dunder methods overloaded for
588588Many of the operators specified have type bounds listed for some of
589589their operands. These should be interpreted more as documentation than
590590as exact type bounds. Trying to evaluate operators with invalid
591- arguments will produce ``Never `` as the return. (There is some
591+ arguments will produce an error. When this happens, the value of the
592+ failed operator is ``Any ``, so that downstream evaluation does not
593+ cascade further errors. (There is some
592594discussion of potential alternatives :ref: `below <pep827-strict-kinds >`.)
593595
594596Note that in some of these bounds below we write things like
@@ -622,10 +624,13 @@ Basic operators
622624'''''''''''''''
623625
624626* ``GetArg[T, Base, Idx: Literal[int]] ``: returns the type argument
625- number ``Idx `` to ``T `` when interpreted as ``Base ``, or ``Never ``
626- if it cannot be. (That is, if we have ``class A(B[C]): ... ``, then
627+ number ``Idx `` to ``T `` when interpreted as ``Base ``, or generates a type
628+ error if it cannot be or if the index is invalid.
629+ (That is, if we have ``class A(B[C]): ... ``, then
627630 ``GetArg[A, B, Literal[0]] == C ``
628- while ``GetArg[A, A, Literal[0]] == Never ``).
631+ while ``GetArg[A, A, Literal[0]] `` is a type error).
632+
633+ If ``T `` is ``Any ``, the result is ``Any ``.
629634
630635 Negative indexes work in the usual way.
631636
@@ -640,15 +645,19 @@ Basic operators
640645 ``Param `` types.
641646
642647* ``GetArgs[T, Base] ``: returns a tuple containing all of the type
643- arguments of ``T `` when interpreted as ``Base ``, or `` Never `` if it
648+ arguments of ``T `` when interpreted as ``Base ``, or an error if it
644649 cannot be.
645650
651+ If ``T `` is ``Any ``, the result is ``Any ``.
652+
646653* ``Length[T: tuple] `` - Gets the length of a tuple as an int literal
647654 (or ``Literal[None] `` if it is unbounded)
648655
649656* ``Slice[S: tuple, Start: Literal[int | None], End: Literal[int | None]] ``:
650657 Slices a tuple type.
651658
659+ If ``S `` is ``Any ``, the result is ``Any ``.
660+
652661* ``GetSpecialAttr[T, Attr: Literal[str]] ``: Extracts the value
653662 of the special attribute named ``Attr `` from the class ``T ``. Valid
654663 attributes are ``__name__ ``, ``__module__ ``, and ``__qualname__ ``.
@@ -688,11 +697,15 @@ Object inspection
688697 methods).
689698
690699* ``GetMember[T, S: Literal[str]] ``: Produces a ``Member `` type for the
691- member named ``S `` from the class ``T ``, or ``Never `` if it does not exist.
700+ member named ``S `` from the class ``T ``, or an error if it does not exist.
701+
702+ If ``T `` is ``Any ``, the result is ``Any ``.
692703
693704* ``GetMemberType[T, S: Literal[str]] ``: Extract the type of the
694705 member named ``S `` from the class ``T ``, or ``Never `` if it does not exist.
695706
707+ If ``T `` is ``Any ``, the result is ``Any ``.
708+
696709* ``Member[N: Literal[str], T, Q: MemberQuals, Init, D] ``: ``Member ``,
697710 is a simple type, not an operator, that is used to describe members
698711 of classes. Its type parameters encode the information about each
@@ -1736,18 +1749,30 @@ This proposal is less "strictly-typed" than TypeScript
17361749
17371750TypeScript has better typechecking at the alias definition site:
17381751For ``P[K] ``, ``K `` needs to have ``keyof P ``. The ``extends ``
1739- conditional type operator narrows the type to help spuport this.
1752+ conditional type operator narrows the type to help support this.
1753+
1754+ It's not possible to define a type alias in TypeScript that fails at
1755+ expansion time, but it *is * possible to do so in this system.
17401756
1741- We could do potentially better but it would require quite a bit more
1742- machinery.
1757+ We could potentially also make this impossible but it would require
1758+ quite a bit more machinery.
17431759
17441760* ``KeyOf[T] `` - literal keys of ``T ``
17451761* ``Member[T] ``, when statically checking a type alias, could be
17461762 treated as having some type like ``tuple[Member[KeyOf[T], object,
17471763 str, ..., ...], ...] ``
1748- * ``GetMemberType[T, S: KeyOf[T]] `` - but this isn't supported yet.
1749- TypeScript supports it.
1750- * We would also need to do context sensitive type bound inference
1764+ * ``GetMemberType[T, S: KeyOf[T]] `` - Make ``GetMember `` have a bound
1765+ requiring the index be a key... but this kind of dependent bound
1766+ isn't supported currently. (TypeScript supports it.)
1767+ * We would also need to do context sensitive type bound
1768+ inference. This is subtle but obviously this sort of thing is done
1769+ at term level.
1770+
1771+ We think that this isn't worth the complexity, and is also not even
1772+ obviously better. TypeScript commonly requires doing many conditionals where
1773+ often it is always intended that they take the true branch--typically
1774+ the false branch returns ``never ``, and these can be quite difficult
1775+ to track down.
17511776
17521777
17531778Potential Future Extensions
@@ -1838,8 +1863,6 @@ simulated in other ways.
18381863 Open Issues
18391864===========
18401865
1841- * What invalid operations should be errors and what should return ``Never ``?
1842-
18431866* :ref: `Unpack of typevars for **kwargs <pep827-unpack-kwargs >`: Should
18441867 whether we try to infer literal types for extra arguments be
18451868 configurable in the ``TypedDict `` serving as the bound somehow? If
0 commit comments