so cool to see some coverage on this! it's been on our list for a while as part of a "TypeScript features you almost definitely haven't seen" sorta-mini-series. maybe we'll have to have you back on the MiTS channel when we get around to this one! Great stuff!
I know that you have a life and ALL... but also you have such a charismatic presence in your videos... You should own it and be willing to make more videos (I hope you could find the time to do that if it makes you happy and are into it)
re: your question on uses for this, my understanding is that the reason this exists (especially in a structural type system) is for performance: it allows the compiler to take "the happy path" a lot faster rather than having to solve all the ways the type could be used. I would agree that it's nice to document to your users how you intend generic inputs to be used but then there's the problem of almost no one knowing about this :P great video!
The depth of knowledge on that priority job boils down to when your network provider yells you you have unlimited data till you run up to the limit and realized you were gas lit. They told you A but A has a catch. Except ts is like let your executor A be just A and nothing but the A. So help me binary. I didn't go over that part 5 times
Just explanation for future me if I ever have to hunt down this E2 error because a restaurant can't say they serve hot and cold drinks and only actually give you cups for cold drinks. Cos a hot drink will shatter the cold drink cup when someone attempts to do that E3 works because the restaurant serves cold drinks but they give you a cup that works fine for both hot and cold drinks and using that cup will work perfectly
7:15 my guess is because of existing types like array. Array is by default covariant on T. If typescript were to complain there than Array couldn't be covariant on T, rather invariant on it. Which imo would make more sense and then they could just make ReadonlyArray covariant.
How come typescript made Array covariant? Arrays should be - as probably all collections. type A = {a: string} type B = A & {b: string} declare const ab: Array; let bad: Array = ab; //so the covariant behaviour from the video bad[0] = {a: "hello"} as A; // since it's now Array we can put A into it const wrongType: B = ab[0]; // but now we get out this value from ab, so it would be B. Except we've put A there through `bad`
Covariance and contravariance are such bad names! I get it using strange mathy names for things like monads and semigroups, that are big concepts, but type narrowing and widening are more than good enough in this case! (not a criticism about you. great video as always!)
so cool to see some coverage on this! it's been on our list for a while as part of a "TypeScript features you almost definitely haven't seen" sorta-mini-series. maybe we'll have to have you back on the MiTS channel when we get around to this one! Great stuff!
Woah, fancy seeing you guys here!
@@offroaders123 haha and same to you!
I know that you have a life and ALL... but also you have such a charismatic presence in your videos... You should own it and be willing to make more videos (I hope you could find the time to do that if it makes you happy and are into it)
In this video, the word "job" is said 83 times.
Only 83? 😅
re: your question on uses for this, my understanding is that the reason this exists (especially in a structural type system) is for performance: it allows the compiler to take "the happy path" a lot faster rather than having to solve all the ways the type could be used. I would agree that it's nice to document to your users how you intend generic inputs to be used but then there's the problem of almost no one knowing about this :P
great video!
yes i remember when this came out ... the main focus was giving library authors the ability to make their types more performant
This is great! Glad you made a video about this.
The depth of knowledge on that priority job boils down to when your network provider yells you you have unlimited data till you run up to the limit and realized you were gas lit. They told you A but A has a catch. Except ts is like let your executor A be just A and nothing but the A. So help me binary.
I didn't go over that part 5 times
Just explanation for future me if I ever have to hunt down this
E2 error because a restaurant can't say they serve hot and cold drinks and only actually give you cups for cold drinks. Cos a hot drink will shatter the cold drink cup when someone attempts to do that
E3 works because the restaurant serves cold drinks but they give you a cup that works fine for both hot and cold drinks and using that cup will work perfectly
Can't wait for new videos!
I think it was the typescript compiler being dumb for not spitting error for "type Queue = {...}" at 07:15.
it does spit error on my end.
7:15 my guess is because of existing types like array. Array is by default covariant on T. If typescript were to complain there than Array couldn't be covariant on T, rather invariant on it. Which imo would make more sense and then they could just make ReadonlyArray covariant.
4:56 For e3, what if I want to access the `level` property from that job? If I pass a "normal" job, the `level` property won't exist, right?
Great.
How come typescript made Array covariant? Arrays should be - as probably all collections.
type A = {a: string}
type B = A & {b: string}
declare const ab: Array;
let bad: Array = ab; //so the covariant behaviour from the video
bad[0] = {a: "hello"} as A; // since it's now Array we can put A into it
const wrongType: B = ab[0]; // but now we get out this value from ab, so it would be B. Except we've put A there through `bad`
Yeah, this shouldnt be possible. Imo Array should be invariant and only ReadonlyArray should be covariant
Another good example of unsound "I don't care" behavior.
🤯🤯🤯
wow.. first time i start to have some foggy clue what covariance and contravariance mens
Excelent ;)
interesting!
Covariance and contravariance are such bad names! I get it using strange mathy names for things like monads and semigroups, that are big concepts, but type narrowing and widening are more than good enough in this case! (not a criticism about you. great video as always!)
Also, knowing that co is latin for “with” and contra is “against” doesn’t help at all! :P
type State = {
get: (key: string) => T | null;
set: (key: string, value: T) => void;
}
export const useLocalStorage = (prefix: string): State => {
return {
get:(key) => {
return JSON.parse(window.localStorage.getItem(prefix + key) || "null");
},
set: (key, value ) => {
window.localStorage.setItem(prefix + key, JSON.stringify(value));
},
};
};