the literal values are used in the source code itself. So
either update all occurrences of "Facebook" in the source code; impossible if it is used in code you don't control.
or just leave it as is and hope nobody complains that it should be "Meta", not "Facebook".
Trade-offs ...
Added bonus: iterability
constallBigTechz=Object.values(bigTechz);// Using type predicates// https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates//functionisBigTechz(name:string):nameisBigTechz{return(allBigTechzasstring[]).includes(name);}constmyFav=bigTechz.Apple;console.log(isBigTechz(myFav));// trueconsole.log(isBigTechz('Walmart'));// falseconstformatter=newIntl.ListFormat('en',{style:'long',type:'conjunction',});console.log(`The BigTechz: ${formatter.format(allBigTechz)}`);// "The BigTechz: Google, Apple, Amazon, and Meta"
I prefer union types over this since it's much less code and is still completely type safe because of how string literal types work. Another benefit over the object example is that you only need to import the type which will not be in the final JS package.
If you don't need to iterate over the options, all you need is union of string literals.
Only use case where I would use the object approach would be if I had an enum of number values that would benefit from using named options, or if I had string values that can be renamed so they are easier to read.
I feel this gets bandied about a lot in TypeScript circles as if "less code" is always an absolute net win under all circumstances—perhaps it's an over-generalization/simplification of the "less code, less bugs" slogan or some kind of hangover from the verbosity of Java.
Whether or not "less code" is an advantage is, as with everything, highly context sensitive.
less code is an advantage if no capabilities are lost and no information is obscured.
less code is a trade off if capabilities are reduced or information is obscured. Now any one individual may not care about the capabilities or information that are being lost but those preferences can be subjective.
For example, in general one is encouraged not to specify the return type of a function in TypeScript. I argue that the return type of a function is part of the function's type and as such is part of its design and should therefore be made explicit (and Rust seems to have the same idea).
"Similar considerations apply to a function’s return type. You may still want to annotate this even when it can be inferred to ensure that implementation errors don’t leak out into uses of the function."
(The fact that an IDE will show the return type is irrelevant if most of your code reading occurs on Github).
Also note that when you use a union:
constfoo:BigTech='Google';
i.e. you need to declare the TypeScript type otherwise TypeScript will assume that it is dealing with a primitive string. Compare that to:
constfoo=bigTechz.Google;
i.e. with the "JavaScript-style object namespacing a group of values approach" TypeScript has all the information it needs to know what is going on—it isn't necessary to supply TypeScript specific information.
So while the union may be less verbose at the site of declaration there is little difference at the site of use.
Now I suspect that I'm in the minority because I prefer the JavaScript version but I don't use TypeScript as a language but as a JavaScript dialect that occasionally makes type information more explicit so that "TypeScript the super-linter" can do its job, so I like to stay as close as possible to the "source material"—though occasionally I may choose to leave explicit type information for my own benefit.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Discussion
"The biggest argument in favour of this format over TypeScript’s enum is that it keeps your codebase aligned with the state of JavaScript"
Thanks @peerreynders !
This is cool.
However, I probably go with Union types in this case since it saves some lines of codes and has more readability in my opinion.
We start with
Then 2021-10-28
No need to change
bigTechz.Facebook
anywhere in your code and more importantly in code you don't control (but that uses your code).With
the literal values are used in the source code itself. So
Trade-offs ...
Added bonus: iterability
Thanks @peerreynders !
Good point!
iterability
can be a big plus.Now your method is starting to look handy! Thank you!
I also use this pattern all the time
I prefer union types over this since it's much less code and is still completely type safe because of how string literal types work. Another benefit over the object example is that you only need to import the type which will not be in the final JS package.
If you don't need to iterate over the options, all you need is union of string literals.
If you need to iterate over the options, there is only one small change needed.
Only use case where I would use the object approach would be if I had an enum of number values that would benefit from using named options, or if I had string values that can be renamed so they are easier to read.
I feel this gets bandied about a lot in TypeScript circles as if "less code" is always an absolute net win under all circumstances—perhaps it's an over-generalization/simplification of the "less code, less bugs" slogan or some kind of hangover from the verbosity of Java.
Whether or not "less code" is an advantage is, as with everything, highly context sensitive.
For example, in general one is encouraged not to specify the return type of a function in TypeScript. I argue that the return type of a function is part of the function's type and as such is part of its design and should therefore be made explicit (and Rust seems to have the same idea).
Effective Typescript (p.85):
"Similar considerations apply to a function’s return type. You may still want to annotate this even when it can be inferred to ensure that implementation errors don’t leak out into uses of the function."
(The fact that an IDE will show the return type is irrelevant if most of your code reading occurs on Github).
Also note that when you use a union:
i.e. you need to declare the TypeScript type otherwise TypeScript will assume that it is dealing with a primitive string. Compare that to:
i.e. with the "JavaScript-style object namespacing a group of values approach" TypeScript has all the information it needs to know what is going on—it isn't necessary to supply TypeScript specific information.
So while the union may be less verbose at the site of declaration there is little difference at the site of use.
Now I suspect that I'm in the minority because I prefer the JavaScript version but I don't use TypeScript as a language but as a JavaScript dialect that occasionally makes type information more explicit so that "TypeScript the super-linter" can do its job, so I like to stay as close as possible to the "source material"—though occasionally I may choose to leave explicit type information for my own benefit.