Earlier quoted context omitted.
I couldn't care less about mathematics, but I do care about making impossible state impossible and types documenting the domain. If you type some state as: isLoading: boolean result: Foo hasError: boolean errorMessage: string | null then you're creating a giant mess of a soup where the state of your program could have a result, be loading and an error at the same time. If you could recognise that the state of your pr…
>encoding that a number is between 2 and 200 What’s the point of this level of autism when you still have to add run time checks?
`satisfies` is my favorite TypeScript keyword (2024)
91–100 of 217 posts
Re: `satisfies` is my favorite TypeScript keyword (2024)
#92Earlier quoted context omitted.
>encoding that a number is between 2 and 200 What’s the point of this level of autism when you still have to add run time checks?
For a function setVelocity() that can accept 1.. Btw, using “autism” to mean “pedantry” leaves a bit of a bad taste in my mouth. Maybe you could reconsider using it that way in the future.
Re: `satisfies` is my favorite TypeScript keyword (2024)
#93Earlier quoted context omitted.
Honestly I just use TypeScript to prevent `1 + [] == "1"` and check that functions are called with arguments. I don't care about type theory at all and the whole thing strikes me as programmers larping (poorly) as mathematicians.
I couldn't care less about mathematics, but I do care about making impossible state impossible and types documenting the domain. If you type some state as: isLoading: boolean result: Foo hasError: boolean errorMessage: string | null then you're creating a giant mess of a soup where the state of your program could have a result, be loading and an error at the same time. If you could recognise that the state of your pr…
class LoadingState extends State {}
class ResultState extends State {}
class ErrorState extends State {}
const state: State = new LoadingState
Generally it's a bad pattern to have dependant fields like your example, but you don't need TS to solve it.Re: `satisfies` is my favorite TypeScript keyword (2024)
#94Earlier quoted context omitted.
For a function setVelocity() that can accept 1.. Btw, using “autism” to mean “pedantry” leaves a bit of a bad taste in my mouth. Maybe you could reconsider using it that way in the future.
Pushing everything to types like this creates a different burden where you're casting between types all over the place just to use the same underlying data. You could just clamp velocity to 200 in the callee and save all that hassle.
Imo this is mostly useful for situations where you want to handle input validation (and errors) in the UI code and this function lives far away from ui code.
Your point about clamping makes sense, and it’s probably worth doing that anyway, but without it being encoded in the type you have to communicate how the function is intended to be used some other way.
Re: `satisfies` is my favorite TypeScript keyword (2024)
#95Earlier quoted context omitted.
The version I was thinking when I wrote the comment is simpler type Flatten = T extends Array ? Flatten : T > The average Typescript dev likely doesn't need to understand recursive conditional types. The average X dev in Y language doesn't need to understand Z is a poor argument in the context of writing better software.
as a person that never touched JS and TS... what's the difference between the two answers?
In other words
Flatten
will give you a union type of 1, 2, 'a', and 'b' const foo: Flatten = 'b'; // OK
const bar: Flatten = 'c'; // Error: Type '"c"' is not assignable to type '1 | 2 | "a" | "b"'
Technically the inference is unnecessary there, if that's you're goal: type Flatten = T extends Array ? Flatten : T
I don't really consider this the type of flattening an array, but `Array>` would be. And this would actually be comparable to the builtin Array.prototype.flat type signature with infinite depth (you can see the typedef for that here[1], but this is the highest level of typescript sorcery)My solution was for flattening an array with a depth of 1 (most people using Array.prototype.flat are using this default depth I'd wager):
console.log(JSON.stringify([1,[2, [3]]].flat()));
> [1,2,[3]]
The type I provided would match those semantics: // 'readonly' added to the 'extends' sections to work on "as const" (readonly) arrays
type FlatArr = Arg extends readonly [infer First, ...(infer Rest)] ?
First extends readonly unknown[] ?
[...First, ...FlatArr] :
[First, ...FlatArr] :
[];
const flatten = (arr: Arr): FlatArr => arr.flat() as FlatArr
const someArr = [1,[2,'a',['b', ['c']]]] as const; // const someArr: readonly [1, readonly [2, "a", readonly ["b", readonly ["c"]]]]
const someArr2 = flatten(someArr); // const someArr2: [1, 2, "a", readonly ["b", readonly ["c"]]]
[1]: https://github.com/microsoft/TypeScript/blob/main/src/lib/es...Re: `satisfies` is my favorite TypeScript keyword (2024)
#96> TypeScript is a wonderfully advanced language though it has an unfortunately steep learning curve An extremely steep one. The average multi-year TypeScript developer I meet can barely write a basic utility type, let alone has any general (non TypeScript related) notion of cardinality or sub typing. Hell, ask someone to write a signature for array flat, you'd be surprised how many would fail. Too many really stop at…
keyof typeof[number] ? uppercase (myNum)
On the other hand, there isn't much Omit, readonly, mutable in existing code bases, so devs have nowhere to learn but documentation.
Then the ground shifts again and –what should be basic stuff – enums are banned, because erasableSyntaxOnly makes life so much easier.
Re: `satisfies` is my favorite TypeScript keyword (2024)
#97Earlier quoted context omitted.
Well, it is the type of that, in TS syntax. Few are the statically-typed languages that can even express that type.
Java: List Python: list[Any] ...what am I missing?
Re: `satisfies` is my favorite TypeScript keyword (2024)
#9899% of my use of `satisfies` is to type-check exhaustivity in `switch` statements: type Foo = 'foo' | 'bar'; const myFoo: Foo = 'foo'; switch (myFoo) { case 'foo': // do stuff break; default: myFoo satisfies never; // Error here because 'bar' not handled }
I generally do this via a `throw UnsupportedValueError(value)`, where the exception constructor only accepts a `never`. That way I have both a compile time check as well as an error at runtime, if anything weird happens and there's an unexpected value.
Re: `satisfies` is my favorite TypeScript keyword (2024)
#99Earlier quoted context omitted.
Pushing everything to types like this creates a different burden where you're casting between types all over the place just to use the same underlying data. You could just clamp velocity to 200 in the callee and save all that hassle.
Casting? Not really - i think you’d only need a couple type checks. Imo this is mostly useful for situations where you want to handle input validation (and errors) in the UI code and this function lives far away from ui code. Your point about clamping makes sense, and it’s probably worth doing that anyway, but without it being encoded in the type you have to communicate how the function is intended to be used some ot…
Re: `satisfies` is my favorite TypeScript keyword (2024)
#100> TypeScript is a wonderfully advanced language though it has an unfortunately steep learning curve An extremely steep one. The average multi-year TypeScript developer I meet can barely write a basic utility type, let alone has any general (non TypeScript related) notion of cardinality or sub typing. Hell, ask someone to write a signature for array flat, you'd be surprised how many would fail. Too many really stop at…