In all fairness, strict TS is almost like Java, as long as you dont use "any" or some stupid typing. We can just ignore the typing and if you don't do weird things you'll almost always get the correct type inferred, specially with the latest versions of TS. TS is not JS
Typescripts type system is better than most popular type-safe language type systems. Discriminated unions, duck typing, intersection types, conditional types, mapped types and so much more.
you should mention the `object` (note lowercase) this is the most generic pure object you can specify, usually useful it you're extended a generic. function foo (bar: T) { return Object.keys(bar) }
Record won't exclude arrays though. If you want to exclude arrays, you'll need to do `Record`. There are a few small corner cases where `Record` is too strict, but those don't come up much in user-land.
You sure? type personData = Record; // This will cause a TypeScript error because it doesn't match the declared type function f(obj: personData) { return obj; } f(["3"]) // Argument of type 'string[]' is not assignable to parameter of type 'personData'.Index signature for type 'string' is missing in type 'string[]'.ts(2345)
I assumed you’d be putting the type in a generic (which is usually what you want - if your use case looks like that, it’s probably fine to just use `object` and allow arrays)
@@theefeoldit's not that arrays have string indexes, it's that arrays have methods, and methods are strings. The symbol trick is a hack that only works because it takes advantage of how index signatures work in the TS type system -- and it's not bulletproof. An interface declared that way -- interface MyInterface { [x: symbol]: unknown } will behave* differently (unfortunately)
One could just type it like this: type Obj = { name: string; surname: string; }; Record is only needed if you want to build a versatile function that handles different objects with the same structure or if you expect an object from an API f.ex. to change property names in the future
@@IStMl Isn't date an object.. The point of this short is specifically to allow objects where the key is of type string and the value is unknown to ts (or similar definitions) but ANY object should accept date
Great shorts normally but I never bump into this issue, which is confusing as you say "by far the most common issue". If it's being passed like that its normally more defined like as an interface, or as you recommend a type. I never go near the Object type directly.
For most programming, you should take the time to define your types clearly. Eg here don't pass i. Record, pass in type or interface with exactly the fields you need in that function, no more or less
There's literally no price of moving to TS. That's the great thing about it. Just wirte your js in a .ts file. You'll lose nothing and whatever you can add a type to you reap the benefit. You don't have to go deep into types. You can just minimize the mistakes.
Sure, now try this and see if you can pass a date object: type Foo = { bar: string; } It will only pass if date has the properties that the object needs. If it doesn't, then it doesn't work, and if it does, great, I won't look for properties other than those necessary. And, for any reason if you need to allow objects of unknown properties then you can just: type Param = { [K: PropertyKey]: unknown };
I knew about Record but then I wanted to type an empty object (to fill with keys and value later) and that turned out to be a problem. Using {} works for the moment.
@@justindouglas3659 Unfortunately no. Outside of some basics, I never needed PHP nor was interested in it. But by searching for PHP tutorials you surely should find a lot of creators and just stick to the one who seems to flow with your prefered style of learning the best.
I think something like this in Python wouldn't be a problem since the language clearly distinguishes between "dictionaries" and objects that are "instances of classes"
Date is an object, most people want it as an object. This is an interesting case where want to exclude Date. According to the Typescript team, you should only use Record utility type when you want a strictly defined dictionary-like object, so your use case here is more of a hack imo. I recommend using a simple conditional type: function processObjectWithoutDate(obj: T extends Date ? never : T): void { // Process the object // ... }
@@unknownguywholovespizza This is a niche case when you want to accept all types except for a single type, therefore “T extends ? never : T” is exactly the type of readable logic you would want. It doesn’t rely on any unintended behavior to work. It works for multiple cases, not just for Dates. And this is the recommended approach from the Typescript team.
Programmer: tells the language that the argument should be an object. Also programmer: passes a Date, which is by definition an object "Woahh why is the labguage allowed this?"
Using an interface/type/class when you are expecting a specific object type is definitely the best option. In the rare case that you want to accept any object except a Date, instead of using his solution, I recommend using a conditional type: function processObjectWithoutDate(obj: T extends Date ? never : T): void { // Process the object // ... }
By far the most common mistake junior devs make is thinking they are smarter than a compiler and throw away readability for pointless char saving ideas. Also doing micro-optimizations on the behalf of readability... Edit: Just waiting for the smartass to write: "less chars = less file weight and possibly less exec time"... the compiler is there for a reason.
Cool. I'll go back to writing code that doesn't break because of a lack of knowledge when it comes to data types and how they are used; ergo needing a whole other language just to over-specify my dataums.
My frustration is anytime I use typescript with a 3rd party library with broken, missing, and overly complicated types. Fighting both Typescript and a new library, is too much. I usually give up and revert to "any."
That record is the same as Map< String, dynamic> in dart programing, actually for dart to be able to work with Json, it needs to be converted to a Map of Strings keys and dynamic values
If you want a custom type for representing JSON objects in typescript, that provides additional type safety then I recommend the following: type JSONValue = string | number | boolean | null | JSONValue[] | Record;
Unknown will throw an error until you check the type. Any will disable type checking and you don't have to check the type before using whatever you want
Hello Kyle you have been of a great help to me in the last few years as a self-taught developer. Right now I need a job. It has been a real issue for me. I have been a developer of self, building projects for clients as a freelance but I really want to go out of this shell and work in real life company. This is a great problem for me. Please I need your help.
@bronzekoala9141 like he said everything inherits from object so there's a lot of potential reason to pass one around and there's plenty of room for mistakes due to how unintuitive something as abstract as object is
I agree, not a common mistake. I’ve been writing typescript for 10 years. This is a weird niche case where you want strictly compile time type checking for any object except a Date. I say strictly compile time cause you could always use runtime validation for Date very easily which most cases would likely use. His advice to never use object I find to be questionable advice, and his suggested use of the Record utility type is wrong according to the Typescript team. Record should only be used when you want strictly typed dictionary-like object. If you want to exclude date just use a conditional type: function processObjectWithoutDate(obj: T extends Date ? never : T): void { // Process the object // ... }
This one doesnt work with interface. I have googled for some solutions, but almost of it are recommended replace type instead or using Record which i see no different from Object/any. Does anyone have another idea!?
You should only use Record utility type when you want a strictly defined dictionary-like object, so his solution is more of a hack. In his example, it’s a simple case where you want to just exclude the Date type, so using a simple conditional type to exclude Date is the best option: function processObjectWithoutDate(obj: T extends Date ? never : T): void { // Process the object // ... }
Trying to make a react query clone and having a hard time wrapping my head around this concept. I want to easily store state values on any given page. This works to pass unknown state types, but now I'm wondering if there is a way to get full typing from the unknown values down stream? Anyone have any advice on this concept?
What we need is a typescript solution... for typescript. And we need more frameworks on top of frameworks on top of frameworks on top of frameworks on top of frameworks. Life feeds on life feeds on life feeds on life feeds on life... You can typescript if you want to. You can leave vanilla js behind... and if your friends dont dance with typescript down their pants, well their no friends of mine. Typesafety Dance 💃 🕺
I always love those videos with devs that are spending couple of minutes here and there just to be type safe instead of focusing on the actual code :D. This is priceless…
@@inzdvlIf you’ve never had a type error before, you’ve never coded in your life. Also, typing enables autocompletion, so that I can focus on the actual code instead of looking for the documentation every time..
They are like the exact opposites. Any allows any operation because it could be anything, unknown allows none without narrowing down the type. It’s better to read the documentation and code examples to really get the gist of it
TypeScript is like an enhanced version of JavaScript. It adds optional static typing to catch errors early, improves coding tools, helps maintain clean and documented code, supports modern features before they’re available in all browsers, and boosts code quality.