6 ms·
> TypeScript got typings right. I have not used TypeScript, but looking at it's documentation the syntax for type annotations look identical. Would you be will
by timothycrosley 7y ago
> TypeScript got typings right.
I have not used TypeScript, but looking at it's documentation the syntax for type annotations look identical. Would you be willing to expand on why you think its approach is better / how it's different?
- scrollaway 7y agoNo importing basic types, using binary operators instead of awful things like Union and bracket accessors and what not, inline interfaces... Try it a bit. it truly is enjoyable. Fifteen years of python and I'm still enjoying TypeScript more. Mypy is limited by annotations having to be compatible python syntax.
- timothycrosley 7y ago> No importing basic type This at least is being solved in Python: https://www.python.org/dev/peps/pep-0563/ https://www.python.org/dev/peps/pep-0563/ > inline interfaces Typed dicts in 3.8 look pretty similar at cursory glance https://www.python.org/dev/peps/pep-0589/ https://www.python.org/dev/peps/pep-0589/ I'll definitely play around with it more!
- scrollaway 7y agoWatch the difference: A variable that can be an object with two elements (one of them being a list of strings), or a tuple of exactly two strings. // typescript let t: {a: string[], b: number} | [string, string] # python 3.8 from typing import TypedDict, Tuple, Union class SomeTypedDict(TypedDict): a: List[str] b: Union[float, int] t: Union[SomeTypedDict, Tuple[str, str]] I had to google a bunch to figure out how to write the Python version, whereas the typescript one was completely natural to write. It takes one line and requires no imports. The interface is inlined. All of this also makes it more readable when you come across it eg. in an IDE tooltip.
- joshuamorton 7y agoGranted, in python, I'd call the use of a typed dict a smell. If you're able to spend the time creating the typed dict, just promote it to a dataclass. Using python ~3.9, this will look like @dataclasses.dataclass # or @attr.s class MyStruct: a: List[str] b: int|float t: MyStruct|Tuple[str,str] But MyStruct will be an actual object that can be manipulated as an object. And if you want to accept any object that fits that interface, instead of just instances of MyStruct, class MyStructTmpl(Protocol): a: List[str] b: int|float Then def f(thing: MyStructTmpl|Tuple[str,str]) -> bool: return True f(MyStruct(a=['a'], b=2)) would typecheck. In JS having the typed-dict type makes sense because you're often working with arbitrary objects with who knows what attributes, but in python that isn't the case. There's fairly succinct and powerful tools (now, anyway) to define record types.
- scrollaway 7y agoI'll give you that in controlled code the use of typed dicts would be a symptom of a code smell, but in less controlled environments where you're dealing with eg. JSON inputs, form inputs, SQL table results and so on … not so. I'm also not onboard the "it's a code smell, it doesn't matter" train. IMO if python adopted the typescript typing syntax we'd all be better for it. I also forgot to mention the atrocious typing syntax for functions. Once again, typescript is a lot more succint and readable.
- joshuamorton 7y ago> but in less controlled environments where you're dealing with eg. JSON inputs, form inputs, SQL table results and so on … not so. I more or less agree with this, but then again, IMO you should be isolating the less controlled code behind a controlled api. And the marginal value of converting `_ConvertQueryResultDictToQueryResult(qr: Dict[str, Any]) -> QueryResult` to something that uses a typeddict instead (which may not be possible, since that function is probably generic) is low. > I'm also not onboard the "it's a code smell, it doesn't matter" train. Emphatically, this isn't what I'm saying. What I will say is that ergonomics encourage certain methods of development. From experience, I'm strongly against the pattern of using a dict as a weak struct. The best comparison I can give is tuple -> namedtuple -> attrs. Namedtuple has absolutely valid uses (when you need tuple semantics, usually for backwards compatibility). But people often use it for any record type, because it's easy and familiar. Dataclasses are usually better, and I'd be happier (and the average python code would be better) if the friction to add a dataclass was lower than the friction to add a namedtuple. Similarly, if the friction to use a dict in place of an object is much lower, people will be encouraged to use dicts in place of objects. This isn't a good thing. That doesn't mean that we absolutely shouldn't try to improve ergonomics across the board, but I'm a strong believer that the language should make doing the right thing easier than doing the wrong thing, and this is often (but not always!) the wrong thing.
- moreati 7y ago> using binary operators instead of awful things like Union Do you mean like https://www.python.org/dev/peps/pep-0604/#id17 https://www.python.org/dev/peps/pep-0604/#id17 ? > Inspired by Scala language [5], this proposal adds operator __or__() in the root type. With this new operator, it is possible to write int | str in place of Union[int,str]
- scrollaway 7y agoYeah. Good to see that's being added.