Live data from Hacker News

Learn how to unleash the full potential of the type system of TypeScript

type-level-typescript.com

71–80 of 256 posts

Re: Learn how to unleash the full potential of the type system of TypeScript

#71
post #50

Earlier quoted context omitted.

Non-soundness is sort of a feature, it lets you force your way through and just say "trust me, this is a Thing" when it's just hard (or impossible) to make TypeScript see that. In practice, you can write large code bases where you only need to do this every 1000 lines or so. Not ideal, but better than no typing.

Is it fair to say that the limitation is that the type checker can admit programs that are not type correct?

That's by design, considering that its original purpose was to introduce static typing in JS codebases.

Re: Learn how to unleash the full potential of the type system of TypeScript

#72
post #40
post #37

One think I struggled a lot with until I got it is that the TypeScript types and the JavaScript code live in totally separate universes, and you cannot cross from the type world to JavaScript values because the types are erased when transpilling - meaning they can't leave any trace. This means that it's impossible to write this function: function isStringType (): boolean { return ... } const IS_STRING: boolean = isSt…

You can use type guards for something similar: https://www.typescriptlang.org/docs/handbook/advanced-types....

What they were getting at is that you can't observe T itself, only values passed in as type T

Re: Learn how to unleash the full potential of the type system of TypeScript

#73

Earlier quoted context omitted.

It's actually not in the standard library, but you can write it yourself: type Expect = T; `T extends true` puts a type constraint on the parameter, which then needs to be assignable to the literal type `true` to type-check.

OK cool, now what about `Equal` :).

type Equal = A extends B ? (B extends A ? true : false) : false;

Re: Learn how to unleash the full potential of the type system of TypeScript

#74
post #61

Earlier quoted context omitted.

Is it fair to say that the limitation is that the type checker can admit programs that are not type correct?

Yes. For example it has the "any" type which will bypass any sort of type check. But I think it's more nuanced. Depends of what you mean by type correct. Even in Haskell you can override the compiler and say "trust me on this".

Any isn’t required. The go-to example of unsoundness is the Cat[] ref that you alias as an Animal[], append a Dog to, then map over the original ref calling ‘meow()’ on each entry.

Re: Learn how to unleash the full potential of the type system of TypeScript

#75

A great idea. Now, everyone that learns this stuff, show some restraint! The drawback of a powerful type system is you can very easily get yourself into a type complexity mudhole. Nothing worse than trying to call a method where a simple `Foo` object would do but instead you've defined 60 character definition of `Foo` capabilities in the type system in the method signature. Less is more.

This is so true. I've been thinking recently that in the same way that "use boring technology" is a pretty well-known concept, so should "use boring types" enter the collective conscious. Type operators are exciting and flashy, but I found that using them too much leads to brittle and confusing types. Saving them for a last resort tends to be the right strategy. Often there's an extremely dumb way to write your types that works just as well - maybe even better :)

Re: Learn how to unleash the full potential of the type system of TypeScript

#76
post #41

Is there any place I could report issues or ask questions about the course other than Twitter? If the author is reading this, the proposed solution to the `merge` challenge is: function merge (a: A, b: B): A & B { return { ...a, ...b }; } That's the "obvious" solution, but it means that the following type-checks: const a: number = 1; const b: number = 2; const c: number = merge(a, b); That's not good. It shouldn't ty…

Yeah, TypeScript gets funky around the boundary of "things that can only be objects", because JavaScript itself gets funky around "what is an object"

Technically TypeScript "object types" only describe properties of some value. And in JavaScript... arrays have properties, and primitives have properties. Arrays even have a prototype object and can be indexed with string keys. So... {} doesn't actually mean "any object", it means "any value"

At its boundaries, TypeScript has blind-spots that can't realistically be made totally sound. So the best way to think of it is as a 90% solution to type-safety (which is still very helpful!)

Re: Learn how to unleash the full potential of the type system of TypeScript

#77

Might as well ask here. On our teams, we have the occasional developer that is insistent on using Typescript in an OO fashion. This has always struck me as square peg round hole. Even though I come from an OO background, Typescript strict settings really seem to push me in a direction of using interfaces and types for type signatures, and almost never classes, subclasses, instantiated objects. I don't have a very goo…

I'll give a practical, non-philosophical answer.

Indeed, if you want to use emitDecoratorMetadata for automatic dependency injection, you should use classes. If the library itself takes advantage (again likely due to decorators) of classes e.g. https://typegraphql.com/docs/getting-started.html then yes, classes are again a fine choice.

The general answer is that they're useful when the type also needs to have a run-time representation (and metadata). Otherwise, not really.

Re: Learn how to unleash the full potential of the type system of TypeScript

#78

my HTML blog only has 30 lines of JS. i didn't need a framework and i certainly don't need types. grumble grumble web should just be simple html javascript grumble serverside render in my pet language grumble /s

Add another 1 to your army. We all know how Typelevel Scala ended.

Re: Learn how to unleash the full potential of the type system of TypeScript

#79
post #53

Earlier quoted context omitted.

An ES module is encapsulated enough. You can dependency inject with them as you wish. It's like having a class, no need for a class inside a class. The biggest argument is that my functional-ish code is always 3x shorter with the same features, though.

This. Creating classes to wrap dependencies is a pattern only needed because of language limitations. With JS/TS, you can mock at the import statement level, so no need to twist your code to abstract away importing. Also, even if you didn't want to mock that way, you can get dependency injection with functions just by taking a parameter for a dependency. If dependency injection is the only reason you have to use a cl…

Request-scoped DI (as seen in ASP.NET MVC) is great on the backend for servicing requests. You can ask for e.g. a class representing the current user information to be injected anywhere, or to keep track of request-associated state like opentelemetry spans, or a transaction, etc. The alternative is to pass the user information class or transaction to all other services, which can be annoying

Its rarely seen in the ecosystem as a solution, unfortunately (everyone is passing all arguments all the time), but its one of the rare places where this is still useful. I've had bad experience with the alternative (continuation local storage) and its not nearly as elegant.

Re: Learn how to unleash the full potential of the type system of TypeScript

#80

Speaking of types, what are your thoughts on fp-ts if you've used it? It brings functional programming concepts like in Haskell such as monads into TypeScript.

If you stick to a few useful types like `Option` and `Either`/`TaskEither` you can get a lot of value out of it when writing server side code, particularly when combined with `io-ts` for safely parsing data.

If you go all in and use every utility it provides to write super succint FP code, it can get pretty unreadable.

Post reply on HN