In Python (typing) one can make a type alias (which is nothing more than a new name for a type) and a NewType, which is a type that is 100% the same as the underlying, but will be treated as unique by the type system. To quickly show the difference:
UserId = int # Alias, meaning it's not considered a new type
def get_user(uid: UserId):
# so this is the same as "def get_user(uid: int):"
...
get_user(3) # and this is valid
UserId = typing.NewType("UserId", int) # NewType, meaning it is considered a new type
def get_user(uid: UserId):
# so this is NOT the same as "def get_user(uid: int):"
...
get_user(3) # and this throws an error (in type checking)
get_user(UserId(3)) # (this works)
user_id = UserId(3)
get_user(user_id) # as does this
Note that also in the case of NewType, at runtime the uid parameter is just an integer, and can be used in exactly that way.
In this trivial example the advantages of NewType are not so clear, but if you have a function with 5 parameters, some user_ids, some user_age, some department_id, etc, it's a life-saver if the type checker can alert you if you enter the parameters in the wrong order (and even better, if the IDE will just suggest the exact variable you need for each parameter, because it knows you have only one variable of type DepartmentId available!)
How to do the same in TypeScipt?
In TypeScript you can easily create type aliases:
type UserId = number
however, how to make something similar to NewType (where the typescript compiler will complain if you assign a simple number to a function that expects a UserId).
(Note that for custom objects, you could make a subclass; this question is mostly aimed at primitive objects (string, number, etc))