5 ms·
With the ‘unknown’ type available is there a good case for ‘any’ anymore? I really like the ‘unknown’ type. In catch statements for example the error is unknow
by quickthrower2 4y ago
With the ‘unknown’ type available is there a good case for ‘any’ anymore?
I really like the ‘unknown’ type. In catch statements for example the error is unknown but you can do dynamic
checks to see what it is,
then typescript lets you treat it that way.
- spankalee 4y agoThe TypeScript team has said that if they could do it over, `any` would behave like `unknown`.
- Kiro 4y agoThat sounds extremely cumbersome. Sometimes I just want to throw an any on something and call a method on it without having to deal with types. How would unknown help with that? I can't call a method on a variable with unknown type.
- haburka 4y agoYou can use ‘as’ to cast unknown to any type. This is extra typing but it does signify to other developers that you’re calling a function on an unverified object, which I believe makes the code more maintainable in the long run.
- anentropic 4y agoWhy bother using typescript then?
- Kiro 4y agoThat 1% won't invalidate the remaining 99%.
- golergka 4y agoThis is a good thing for serious, long lasting projects. However, it could be an overkill for something fast and dirty. One thing I love about typescript that I've never seen in other languages is that you can adjust the type checker exactly for the level of rigidness that project at hand needs. Any is okay for 200 LOC quick prototypes.
- Gigachad 4y agoThis is a bit of a problem imo. It’s super easy to forget to add a type somewhere and then it just defaults to any. I’d prefer no implicit any so you have to knowingly set something as untyped. It’s also just flat out impossible in many other languages because the compiler actually needs to know the types for performance reasons.
- gchq-7703 4y agoThis is possible with a single `tsconfig.json` change[0]. This is also the default mode if you've set the 'strict' flag. [0] https://www.typescriptlang.org/tsconfig#noImplicitAny https://www.typescriptlang.org/tsconfig#noImplicitAny
- mablopoule 4y agoYes, exactly. Typescript managed to be the best of both worlds, as you can be both lenient when you're still in the design/prototyping phase of a project, and need to test idea quickly, but also add as much type-check as you see fit when you're maintaining a project, and need to interface with lots of existing code. As such, I'm always a bit miffed when I see so many people adamant on setting it to maximum strictness by default, under the guise of "best practice".
- moogly 4y agoAs someone who has "strictified" a lot of code bases after the fact, starting out with `strict` is way less friction than adding it later on. Especially `strictNullChecks`. It's a massive headache to deal with that later on.
- eyelidlessness 4y agoYup. And strict mode tends to guide devs towards better code/API design. Stuff like function/method overloads with dynamic argument types might seem convenient when the types are loosey goosey, but it usually becomes obvious they’re probably a bad idea when you have to specify the types upfront.
- bazoom42 4y ago‘any’ is great for porting javascript into typescript, and integrating with javascript libraries. You can add types gradually, without everything grinding to a halt.
- schwartzworld 4y agoAdding types to code that was written with `any` is going to be much harder than using `unknown`.
- bazoom42 4y agoThe point is if you have existing JavaScript you want to integrate with TypeScript. You should not need ‘any’ in code written in TypeScript from the beginning.
- schwartzworld 4y agoSure, but at least with unknown you will have done some narrowing. Writing Typescript well requires some fundamentally different patterns than javascript. Adding types afterward is like pulling out your teeth slowly.
- capableweb 4y agoFor one, it signals different intent, which tends to be important in larger projects with more collaborators. The more you can make intentions obvious, the easier it'll be for others to understand and contribute. A value whose type we don't know is different from a value which we know could be any type.
- bluepnume 4y agoThose sound like the same thing to me.
- blowski 4y agoConsider a ‘dump’ function. By design, it handles anything you throw at it - strings, objects, booleans, etc. It won’t change. That’s ‘Any’. Whereas ‘Unknown’ might be a stepping stone to introduce a more specific type once all the use cases are known. I let it handle strings and integers, log a line about any other type that calls it, and continue behaviour as it is today.
- dtech 4y agoSuch a `dump` function would be 100% the same with unknown, since all types can be converted to top types (both any and unknown in TS)
- badlucklottery 4y agoThe difference comes when you interface with other well-typed code and want to convert from any/unknown down to a specific type. For example: function handleString(s: string) { //... } declare const a: any; declare const u: unknown; handleString(a); // works with zero intervention handleString(u); // error: Argument of type 'unknown' is not assignable to parameter of type 'string' handleString(u as string); // works again with explicit re-typing
- capableweb 4y agoA dump function accepting "unknown" is signalling "I'm not sure what this function could handle, probably a lot of different types" vs accepting "any" where it's telling you "I can accept any type you throw at me".
- 9034725985 4y ago> With the ‘unknown’ type available is there a good case for ‘any’ anymore? Lets say you have some input json that you want to slightly modify to something else. How would you do this with unknown? I can't just blindly replace any with unknown. I'd get errors like this: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'unknown'.ts(2407) For example, how can I do this better? Remember the input json could be pretty much anything. I don't have a spec other than I only care about things that end with __c. https://github.com/kusl/salesforcecontactmapper/blob/eff0b3eba893d562a002b9d85931524954de8171/src/main.ts#L4 https://github.com/kusl/salesforcecontactmapper/blob/eff0b3e... import { Output } from "./Output"; import { Preference } from "./Preference"; export function MyMap(input: unknown): Output { const mypreferences = Array<Preference>(); for (const prefCode in input) { if (prefCode.endsWith("__c")) { if (prefCode === "IsInternalUpdate__c") { continue; } let currentValue = ""; if (input[prefCode] !== null) { currentValue = input[prefCode].toString(); } if (currentValue === "true") { currentValue = "True"; } if (currentValue === "false") { currentValue = "False"; } const preference: Preference = { PrefCode: prefCode, CurrentValue: currentValue } mypreferences.push(preference); } } const myOutput: Output = { ContactId: input.Contact__c, Email: input.ContactEmail__c, IsInternalUpdate: true, Preferences: mypreferences } return myOutput; }
- mxz3000 4y agowell you expect 'input' to be something that you can iterate over, so clearly using any is wrong here.
- 9034725985 4y agoyes, input is a json of some kind. You could say technically could be simply { "Unsubscribe__c": false } or even {} both of which are silly in my case because there is no key for me to identify who the person is but they are valid inputs. Or the test case I have is https://github.com/kusl/salesforcecontactmapper/blob/eff0b3eba893d562a002b9d85931524954de8171/test/input.json#L16 https://github.com/kusl/salesforcecontactmapper/blob/eff0b3e... Or the input could have a thousand key values and I only care about some of them. What should my object look like? How do I create a class that says everything that ends in "__c" is something I care about? I tried unknown. I tried Object. How do I fix this (and learn something so I fix all future code I write)?
- nicoburns 4y agoIt's can be useful when you're integrating with 3rd party that doesn't support typescript and you just want to say "I don't care about types here". Of course you have to be careful as `any` turns off typing everywhere it appears. But if the usage is local within a function then this may not matter too much.