TypeScript in 5 minutes
typescriptlang.org
typescriptlang.org
What’s scary is the number of bugs in the original implementation! I made the comment on Reactuflux’s #typescript channel that I’m afraid to use code not written in TS now.
Anyway, it’s been interesting coming from the land of Python, and surprisingly quite enjoyable.
The Bulma library I’ve re-written and released on npm is https://www.npmjs.com/package/rbx
For example, in React there is this type that's a union of an array, single object or null. Some kind of catch-all, I guess. So, when you see one of these things, there's no way to know what you have unless you do something ugly like this:
if ((value as any).length) {
// it's an array
} else if (value) {
// must be a single object, I guess..
} else {
// null
}
The thought of littering my code with these kinds of type checks makes me feel really dirty, unless I'm totally missing something... if (value == null) {
// TS knows value is null, doesn't let you access value .length for example
} else if (Array.isArray(value)) {
// TS knows value is an array
} else {
// TS knows that it's an object here
}
However, having types like those in your own code (e.g. things like X[] | Y | null) is probably an antipattern and should be avoided. Using discriminated unions[2] is much better.[1]: https://www.typescriptlang.org/docs/handbook/advanced-types.... ("Type Guards and Differentiating Types" section) [2]: [1]: https://www.typescriptlang.org/docs/handbook/advanced-types.... ("Discriminated Unions" section)
But, as you say, pattern matching sum types is a weak point in practical use of TypeScript.
Since the types only exist at compile time, maybe there could be a heavier opt-in system that uses something like Symbols to do pattern matching:
matchable type Shape = Circle | Square | Triangle;
const myShape: Shape;
match myShape {
// uses symbol magic under the hood, eg. if (SymbolShapeCircle in o)
case (c: Circle) { ... }
case (other: Triangle | Square) { ... }
} interface Tagged {
tag: string;
}
interface Circle extends Tagged {
tag: 'circle'
}
// ... Other implementations
switch (myShape.tag) {
case 'circle': {
// Do circular things
}
// etc . . .
}
You'll occasionally even see this in Scala code, since the @switch annotation optimizes pattern-match statements[2].1. https://www.typescriptlang.org/docs/handbook/advanced-types....
2. https://www.scala-lang.org/api/2.12.x/scala/annotation/switc...
It is also the best place to start evaluating how "complete" a solution is; particularly when faced with multiple choices.
It was a tutorial very similar to this one that led me to choose flow over typescript - I did the equivalent of setting the "user" in this example to null, flow would tell me it wouldn't work and typescript just happily compiled away. In short, this kind of quick evaluation led me to deduce typescript is JS with loose types sometimes (but you aren't sure where) so as not to be annoying and flow is JS with restrictive types everywhere (that may not get your indirect but correct logic) so as to provide the most guarantees.
There’s a “strict” flag that you can use to turn on most of the more specific strictness flags all at once.
"compile": "tsc -p ./tsconfig.json",
I also have a start script, for running it from the command line: "start": "npm run compile && node ./.build/main.js"
tsc has some kind of file-watching mode, that I assume compiles when you save stuff, but I don't use that, because I'm not a monster.The public modifier on these constructor parameters is actually introducing them as properties of the Student type:
constructor(public firstName: string, public middleInitial: string, public lastName: string) {}
Since the Student type has 'firstName' and 'lastName' properties, it meets the Person interface requirements. It doesn't need to declare that it is, but could and usually would just for readability and the additional assurance that you haven't forgotten something.
No, you don't need to inherit or implement which is one of the great features of TypeScript!
In this example, the `greeter` function accepts any object that has a `firstName` and `lastName` property defined, regardless of what the object/type is called. No need for inheritance.
In fact, the `Person` interface is not even emitted in the JS output because interfaces are only used at compile time, not at run time.
Incidentally, to which porn sites are you referring? Which of your favorite porn sites do you think do the best job with UI/UX?