I'm so happy powerful type systems are more popular now. TypeScript bringing a great type system to a language as popular as JS is fantastic. Rust is also a great way to get a great type system while staying in a systems programming and procedural environment. Hell, even python type annotations support union types. I never knew the depth of type systems until the last year when I took a type theory course and a compi…
Tricks I wish I knew when I learned TypeScript
231–240 of 276 posts
Re: Tricks I wish I knew when I learned TypeScript
#232Earlier quoted context omitted.
Me, reading the link at the top of this thread: oh wow, those are really cool. Me, reading this example: oh no, those all need to be added to our project's lint rules to make sure no-one uses them.
Why would you prevent their usage? They're incredibly helpful
Re: Tricks I wish I knew when I learned TypeScript
#233Earlier 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.
Why write code like that, instead of extending the class with a mandatory property? The above code is going to be inscrutable to a lot of engineers, and this isn't something like an ORM where there's a good reason for that.
Even though the code may seem inscrutable, note that the resulting type is fairly easy to understand in your IDE. That is, if you hover over the "B" to see what the type definition is, you see:
type B = A & {
foo: number;
baz: number;
}
If you defined the type like this (which is equivalent to extending the class as you were proposing) and later on someone changes the type of one such mandatory properties in the base and/or extended class without changing the other, the error becomes much much weird, on the lines of:> Type 'number' is not assignable to type 'never'.(2322)
Here typescript is saying that a prop cannot have a value (type never) because the base class defines it as "number?" but the extended one defines it as "string", and the intersection between them is empty. This is hard to understand when it pops out where you don't expect it. Harder than ignoring the weird "Ensure" thing, seeing what it does (the resulting type B definition) and moving on.
Defining advanced types may be cumbersome, but dealing with code that uses them is still approachable. This allows the more experienced team members to "shape the ground" and less experienced members still reap the benefits even if they don't fully understand how the thing works.
Re: Tricks I wish I knew when I learned TypeScript
#234Earlier quoted context omitted.
The core problem here is that you don't actually want to check if something is an object, but whether it matches the Human type. The correct way to do that is to define a type guard [0], for example: function isHuman(input: any): input is Human { return ( Boolean(input) && Object.prototype.hasOwnProperty.call(input, "name") && Object.prototype.hasOwnProperty.call(input, "age") ); } There are libraries which can autom…
> There are libraries which can automate this for you which is the route I would recommend Which libraries do you recommend? I've had to do this a couple of times in my current project and it's painful (and I made mistakes).
[0] https://github.com/arcanis/typanion
Re: Tricks I wish I knew when I learned TypeScript
#235Earlier quoted context omitted.
> 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…
Re: Tricks I wish I knew when I learned TypeScript
#236Still working on this, but might give someone a laugh :) Problem 1 from Project Euler in TypeScripts Types https://github.com/iiTzEddyGG/typing-euler/blob/master/src/p...
I am highly interested in type programming lately, exactly the kind of thing you're doing here. Do you have any other resources that inspired you? Here are some of my favorites: https://gist.github.com/hediet/63f4844acf5ac330804801084f87a... https://github.com/codemix/ts-sql https://github.com/jamiebuilds/json-parser-in-typescript-ver... https://gist.github.com/acutmore/9d2ce837f019608f26ff54e0b1c...
Re: Tricks I wish I knew when I learned TypeScript
#237Earlier quoted context omitted.
Why write code like that, instead of extending the class with a mandatory property? The above code is going to be inscrutable to a lot of engineers, and this isn't something like an ORM where there's a good reason for that.
The advantage here is that you are not repeating the type of the property twice (once as optional in the base type, once as mandatory in the extended class). Even though the code may seem inscrutable, note that the resulting type is fairly easy to understand in your IDE. That is, if you hover over the "B" to see what the type definition is, you see: type B = A & { foo: number; baz: number; } If you defined the type l…
The advanced programmer simply writes "type Ensure = T & { [U in keyof Pick]-?: T[U] };", thus removing the need to copy the property.
The master programmer copies the property definition.
Re: Tricks I wish I knew when I learned TypeScript
#238Does Typescript get better? I've been forced to use it for my most recent project, but haven't been given any time to read through the documentation. I've found that I'm spending about 99.9999% of my development time trying to figure out how to get my IDE to not show that their are typescript problem. At this point I hate typescript with the burning fury of a trillion suns. I wonder if this is everyone else's experie…
Re: Tricks I wish I knew when I learned TypeScript
#239The 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.
The type itself is fine but how it is checked and used is not. The following would be better, and in this case you will also have a Human type inside the forEach callback: // ... other code type Human = { name: string; age: number } const isHuman = (obj: unknown): obj is Human => obj && typeof obj === 'object' && 'name' in obj && 'age' in obj; // you can complete the gaps here and also check the property types someAr…
Re: Tricks I wish I knew when I learned TypeScript
#240I actually don't really like Record types in the way people/library maintainers often use them - the type-checker asserts that values are actually present for all the specified keys, which is fine if the objects with the Record type really were exhaustive; but instead I often see them used where the reality of the data is a Partial - some keys are missing. Something about the abstraction causes people to misuse it fr…
Yep, and in your own code you can tell TS to verify your property access with the setting `noPropertyAccessFromIndexSignature` ( https://devblogs.microsoft.com/typescript/announcing-typescr... ) The TS crew did discuss having a "pedantic" mode, which is stricter than "strict", but I don't think it's on the roadmap any more.