r/typescript • u/serg06 • Apr 13 '24
After using Ruby for 2 years, here's some features I'd like to see in Typescript.
Context
I love TypeScript. It's my favorite language. I maintain a medium size project (650 files / 30k lines) written entirely in TypeScript, and there's no other language I'd rather use.
2 years ago, I started a new job using Ruby. While I don't like it nearly as much as TypeScript, it has some amazing features that I wish TypeScript had.
Note: I am NOT saying TypeScript is a bad language! These are just things I miss when I use it.
Desired improvements
1. Returning values from if blocks
const result = if (is_dog) {
'dog';
} else if (is_cat) {
'cat';
} else {
'unknown';
}That code works in Ruby and Rust, but not in TypeScript.
Alternatives:
Downside: Only works for small ifs.
Downside: Have to write
(async () => {})()each time
Setting
let result: string | undefined = undefinedfirst, then assigning it in the if expressionDownside: Can't use
const.
2. Implicit returns
function getResult() {
3;
}
const a = getResult();That code returns 3 in Ruby and Rust, but not TypeScript. It may seem small, but it gets really useful for nested functions and ifs.
Alternatives:
Typing
return 3;instead.
3. Named arguments
function countOccurrences(arr: number[], value: number) {
return arr.filter(x => x === value).length;
}
const occurrences = countOccurrences(arr: [3, 3, 2, 3, 5], value: 3);That code works in Ruby, but not in TypeScript.
Alternatives:
Use positional arguments
Downside: It's easy to mix up the order, and hard to change the order later on, making it less maintainable.
Create an interface for the arguments, and take in an object with that interface
Downside: It's harder to define default arguments.
Edit: You can also write it like this:
function countOccurrences({arr, value = 0}: {arr: number[], value?: number})Tiny downside: You need to write each argument name (e.g. arr) twice.
4. An amazing iterator library
const arr = [3, 1, 2, 3, 4, 5, 5, 5]
const how_many_numbers_occur_twice = arr
.group_by(x => x).values.count(x => x.length == 2)That code works in Ruby and Rust, but not in TypeScript.
Alternatives:
Use Lodash's functions
Downside: You need to order this backwards:
_.count(Object.values(_.group_by(...and so on.
Use Lodash's custom list object
Downside: You're left with a custom list object, not a pojo.
5. Using ? and ! to convey meaning
// ? conveys that it's a predicate
function checkIfDog?(animal: Animal);
// For a function that can return null, ! conveys that it'll throw an error instead of returning null
function loadAnimal(id: string): Animal | null;
function loadAnimal!(id: string): Animal;
// For a function that modifies an iterable, ! coveys that it'll modify it in place
function sort(arr: number[]): number[];
function sort!(arr: number[]): void;That code works in Ruby, but not in TypeScript.
Alternatives:
For predicates:
function isDogFor null-able functions, copy Prisma:
function loadAnimalOrThrowFor functions that don't modify an iterable:
function sort(arr: readonly number[])
Conclusion
For people that got this far: What do you think? Do you want these features in TypeScript, or is the language better without them?
