I think the goal, though, would be to assert that the type is altered, which would involve protocols. (The incoming class doesnât necessarily have a new_attrib attribute, the resulting class does.)
Also, mypy at least rejects the attempt to create an attribute that an arbitrary type T doesnât already have.
Hmm, which immediately unsolves the problem because then mypy thinks âtype[_T] has no attribute ânew_attribââ again. Which is correct, but the whole point of the decorator is to add that attribute.
If you want type checkers to be able to recognize that the return type is both compatible with the passed class as well as with HasNewAttrib, what youâd need is an intersection type. This is unfortunately a well known missing feature in Pythonâs type system. I think the best you can do for now is a union.
You can find some more info on the status of intersection types in links contained in this comment:
For more inspiration, you can take a look at how @dataclass is type hinted in typeshed. Note that even though @dataclass adds an attribute (__dataclass_fields__), its type hints canât express that: