Live data from Hacker News

Tricks I wish I knew when I learned TypeScript

cstrnt.dev

101–110 of 276 posts

Re: Tricks I wish I knew when I learned TypeScript

#101
post #90

Earlier quoted context omitted.

Typescript is actually a great language. And with those utility types, you can do pretty fun stuff like, for example, you want to mutate a type so that some fields become mandatory: type Ensure = T & { [U in keyof Pick ]-?: T[U] }; class A { foo?: number; bar?: number; baz?: number; } type MandatoryFields = "foo" | "baz"; type B = Ensure ; const b: B = { foo: 42 }; Here, ts will complain that b is missing baz.

This seems extremely hard to read for me, I would have an hard time trying to understand what it does if I found it in any source code

    type Ensure
I define a type called Ensure

    
This type takes two type parameters, one called T and the other K which will consist of Keys belonging to the type T (in our case, "foo", "bar" or "baz").

    = T & 
This new type (called Ensure) will be equal to the union of two types: One will be T and the other will be:

    { [U in keyof Pick]
A new type which keys will be picked among the key listed in K

    -?
To which we will remove the potential optional qualifier

    : T[U] };
And which types will be the same as in T.

Re: Tricks I wish I knew when I learned TypeScript

#102
post #8

Here's another. Instead of returning Sometype|undefined from a function which may or may not have a value to return (such as searchCustomer), return Sometype|null. That forces the function to return a value that's explicitly intended rather than defaulting from a missed out if-else codepath. This is useful since JS is often imperative style code.

The difference between null and undefined in JavaScript is something I wished had never been implemented. Other languages refer to null as their billion dollar mistake, but somehow JavaScript got 2 of them with slightly different but sometime identical behaviour. I would defer to eslint to prevent this particular issue if you care about it, this allows you to set rules in your own code without any impact to the outsi…

I disagree. `null` in TypeScript is equivalent to `None` in many other typed languages. `undefined` in Typescript is like null in other languages, with the caveat that if you’re working to transition an untyped codebase and trying to bring types, there may be a useful place for `undefined` in order to express that there is a lack of safety / strict-handling in that area.

I’m still not sure about Error handling, though. Seems feasible that in a fully typed project, any possible unhandled error type could raise a compile error. AFAIK there’s nothing (beyond catch + exhaustive switch) to handle exhaustive error checking in TypeScript, nor is there lib support for handling it either.

Re: Tricks I wish I knew when I learned TypeScript

#103

Is there ever a reason to use interface over type? From what I’ve seen it looks like they can both do the same thing but with slight differences in syntax

They are very similar, but they are subtly different in ways that might matter, depending on what you want to do.

A type is statically-"tagged" data from the typechecker's point of view. Even if `Foo` and `Bar` are two types with the exact same fields, the typechecker won't let you use as Foo as a Bar or vise-versa unless you've explicitly declared that Foos are Bars (via type aliasing or inheritance).

An interface declares a whole category of types that are equivalent: anything with the same "shape" as the interface will count as the interface. So you can pass objects, child objects, objects with additional fields attached, etc. to an interface input; if the thing has the fields the interface cares about, it'll accept it.

Which you want to use depends on what precisely you intend to do, but interfaces are handy in TypeScript where they may be less useful in some other languages because the underlying JavaScript is so "duck-typed" and sloppy on what it means for something to "have a type;" interfaces often model more accurately the behavior of "native" JavaScript functions (that will take an argument, assume it's an object, and just start touching some fields on it without caring whether more fields exist or not).

Re: Tricks I wish I knew when I learned TypeScript

#104

I haven't used typescript much but it's surprising to me that you can pass a `const` value to as an argument which is not `ReadOnly`. Does `const` not really mean anything?

`const` means a constant pointer, but doesn't guarantee that the data it points to will remain constant.

In practice, functions, numbers, bigint, symbols, booleans, strings, regex literals, null, and undefined are all immutable. Since you can't change the value, a const to one of these guarantees the value will never be modified.

Objects, arrays (actually just objects with a different constructor), maps, sets, TypedArrays (real arrays), etc are different. You can be guaranteed that you will be pointing to the same object instance because there's no way to swap out data at a location in memory like there is in low-level languages (yay GCs). The entries inside the hashmap or array can be modified though.

Calling `Object.freeze()` will lock down an array or object with some caveats. Sub-objects will still be modifiable (though you could recursively freeze) and this doesn't work for Map or Set (their properties like get/set/forEach will be frozen, but not the actual data) and it will throw if used on a typed array.

Re: Tricks I wish I knew when I learned TypeScript

#105

The third example describes something useful in record types, but goes about it in what seems an odd way, and ends up suboptimal as a result. I'd instead use an object type like this: type Human = { name: string; age: number; } which also enforces value types in the compiler, rather than requiring runtime guards.

I think the example is a bit contrived with a preset union. Where it’s really valuable is when you’re extracting a union from another source (like via keyof) and want to keep the two objects in sync without having to modify the keys in two places.

Re: Tricks I wish I knew when I learned TypeScript

#106
post #27

I haven't used typescript much but it's surprising to me that you can pass a `const` value to as an argument which is not `ReadOnly`. Does `const` not really mean anything?

That’s a JavaScript specific nuance that typescript inherits. ‘const’ declares a variable with an immutable reference, not an immutable value. If you’re referencing a simple literal like a string or a number that’s effectively the same thing but for objects (and arrays under the hood of JavaScript are fancy objects) while the reference to your given object is constant, the properties of that objects are still mutable…

Correct. This is a thing you can do in JavaScript (and TypeScript) that sometimes trips new people up but is exactly what these keywords mean:

  const foo = [];
  foo.push(1,2,3);

Re: Tricks I wish I knew when I learned TypeScript

#107
post #65

Everything that TS does JS libraries do better without the horrible tradeoffs ... sadly MS has invested so much into promoting it that it's now almost a requirement for all software development.

> Everything that TS does JS libraries do better Which ones do you need to do everything TS does? > without the horrible tradeoffs Which tradeoffs are horrible?

Not OP but I do tend to avoid TS. I don't like the additional friction of working with the language (transpiling, unable to copy/paste directly into an interpreter). I also feel like the community at large writes awful baroque code that makes me want to die. Why use a function when 18 classes subclassing eachother across 4 files will do? If you're familiar with the tiktoker @khaby.lame, TS feels like exactly the over-complicated life hacks he mocks.

Re: Tricks I wish I knew when I learned TypeScript

#108
post #27

I haven't used typescript much but it's surprising to me that you can pass a `const` value to as an argument which is not `ReadOnly`. Does `const` not really mean anything?

That’s a JavaScript specific nuance that typescript inherits. ‘const’ declares a variable with an immutable reference, not an immutable value. If you’re referencing a simple literal like a string or a number that’s effectively the same thing but for objects (and arrays under the hood of JavaScript are fancy objects) while the reference to your given object is constant, the properties of that objects are still mutable…

Same in a lot of programming languages. A common source of errors too. Maybe it is a bit more confusing in JS simply cause people have been taught to make an active choice between var, let and const.

Re: Tricks I wish I knew when I learned TypeScript

#109

Earlier quoted context omitted.

The difference between null and undefined in JavaScript is something I wished had never been implemented. Other languages refer to null as their billion dollar mistake, but somehow JavaScript got 2 of them with slightly different but sometime identical behaviour. I would defer to eslint to prevent this particular issue if you care about it, this allows you to set rules in your own code without any impact to the outsi…

I disagree. `null` in TypeScript is equivalent to `None` in many other typed languages. `undefined` in Typescript is like null in other languages, with the caveat that if you’re working to transition an untyped codebase and trying to bring types, there may be a useful place for `undefined` in order to express that there is a lack of safety / strict-handling in that area. I’m still not sure about Error handling, thoug…

Which language has both a "None" and "null"?

Re: Tricks I wish I knew when I learned TypeScript

#110

I think the unknown example is good but also somewhat confusing, because implicit typing would understand what set of types could be in that array at that moment. Is there another example someone could give for unknown which isn't handled by implicit typing?

  interface ServerResponse {
    data: unknown;
  }
... this is the most common way I see unknown used. Then when you fetch data from the server, you are reminded by the compiler that you should do some duck-type checking on it to make sure it's shaped correctly (since responses from a server can be any shape; is it a 200 with your data, or did a caching layer vend you an old version of this data structure, or is something catastrophically wrong and you're seeing a 200 where the payload is HTML saying "Set up your apache server," etc.)

BTW, TypeScript has another useful tool for tying the runtime typing and static typing together: type guards.

  function isUserRecord(x: unknown): x is UserRecord {
    return (x as UserRecord).name !== undefined;
  }
This is a boolean function but the type system understands that in codepaths where it returns true, the 'x' argument is known to have the UserRecord type. Great for codifying your type-discernment logic.
Post reply on HN