Live data from Hacker News

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

type-level-typescript.com

51–60 of 256 posts

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

#51

Course is probably great, but I find it really weird and unnecessary to describe Typescript type system as Turing complete. Who cares?

People who are trying to statically describe the behavior of highly dynamic JavaScript code.

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

#52
post #46

Earlier quoted context omitted.

> And I don't know how to express the correct solution (i.e. where we actually assert that A and B are object types). You can do this: function merge , B extends Record >(a: A, b: B): A & B { return { ...a, ...b } } const result = merge({ a: 1 }, { b: 2 })

Why Record and not object?

Linters for TypeScript recommend using `Record` instead of `object`, since using the `object` type is misleading and can make it harder to use as intended.

See:

- https://typescript-eslint.io/rules/ban-types/

- https://github.com/typescript-eslint/typescript-eslint/issue...

- https://github.com/microsoft/TypeScript/issues/21732

- https://github.com/microsoft/TypeScript/pull/50666

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

#53

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…

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 class, you probably shouldn't use a class.

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

#54
post #50

Nice course, and nice site. Although, as a Haskell developer, I am curious what type system TS is using (System F? Intuitionist? etc) and what limitations one can expect. Aside from the syntax of TS being what it is, what are the trade-offs and limitations? I was under the impression, and this was years ago -- things are probably different now?, that TS's type system wasn't sound (in the mathematical logic sense).

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?

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

#55
post #46

Earlier quoted context omitted.

> And I don't know how to express the correct solution (i.e. where we actually assert that A and B are object types). You can do this: function merge , B extends Record >(a: A, b: B): A & B { return { ...a, ...b } } const result = merge({ a: 1 }, { b: 2 })

Why Record and not object?

    Avoid the Object and {} types, as they mean 'any non-nullish value'.
    This is a point of confusion for many developers, who think it means 'any object type'.
https://github.com/typescript-eslint/typescript-eslint/blob/...

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

#56
post #46

Earlier quoted context omitted.

> And I don't know how to express the correct solution (i.e. where we actually assert that A and B are object types). You can do this: function merge , B extends Record >(a: A, b: B): A & B { return { ...a, ...b } } const result = merge({ a: 1 }, { b: 2 })

Why Record and not object?

Because you only want to merge two objects that have keys with string type. "object" is represented as Record. That would mean, you can use any type as key. Here is an example:

  function merge(a: A, b: B): A & B {
    return { ...a, ...b }
  }

  const result = merge(() => {}, () => {}) // should fail!
  const anotherResult = merge([1, 2], [3, 4]) // should fail!
Which is obviously not what you want.

This table here gives you a good overview of differences between object and Record: https://www.reddit.com/r/typescript/comments/tq3m4f/the_diff...

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

#57
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…

Does TypeScript support dynamic dispatch? JS by nature is dynamically typed you should be able to introspect at get the type at runtime.

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

#58

Didn't know `Expect` existed. Can't find it docs?

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.

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

#59
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 might be interested in DeepKit[0]. In short, it enables introspection/reflection of typescript types at runtime, and builds off of that to do super interesting things like an ORM, an API framework, ... etc.

[0] https://deepkit.io/

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

#60

Course is probably great, but I find it really weird and unnecessary to describe Typescript type system as Turing complete. Who cares?

People who are trying to statically describe the behavior of highly dynamic JavaScript code.

Yeah but how is Turing completeness directly relevant to that? Article doesn't seem to explain, just says "Turing Complete" in the title. Again, so what? I suppose it's somewhat indirectly vaguely reassuring?

P.S. You might like this http://beza1e1.tuxen.de/articles/accidentally_turing_complet...

Post reply on HN