10 TypeScript Coding Challenges

Want to try it?

Zachary Lee
Frontend Weekly
4 min readJul 18, 2022

--

Photo by Alexandru Acea on Unsplash

In this article, I’ll introduce you to 4 TypeScript coding challenges. I hope it can help you.

1. Get the variable type

Using typeof T we can directly get the type of a variable, which is not the same as typeof in JS.

const person = {
name: '1',
age: 2,
};
// type Person = {
// name: string;
// age: number;
// }
type Person = typeof person;

Note that we can only receive this type using the type keyword, not interface. If you are interested in their difference, this article of mine covers it in detail:

2. Get the key of type

Using the keyof keyword, we can get the type of the key of a type, which is usually a union type.

const person = {
name: '1',
age: 2,
};
// type Person = {
// name: string;
// age: number;
// }
type Person = typeof person;
// "name" | "age"
type K = keyof Person;

3. Condition type

The extends keyword can determine whether one type is assignable to another type. Usually we use it to limit the type or judge the type to get the desired result.

// Restrict parameter types using generics
const wrapper = <F extends Function>(fn: F) => {
const ret = fn();
return ret;
};
// OR
type isNumber<T> = T extends number ? true : false;
type T1 = isNumber<number>; // true
type T2 = isNumber<string>; // false

4. Indexed access types

Like getting a value in JavaScript, we can get the type of a value in TypeScript.

type Person = {
name: string;
age: number;
};
// string
type PersonName = Person['name'];

5. Type elimination

never in TypeScript can be used for type elimination, for example:

type Person = {
name: string;
age: number;
};
type CustomExclude<T, U> = T extends U ? never : T;// type A = "age"
type A = CustomExclude<keyof Person, 'name'>;

For more secrets about never check out:

6. Built-in utility types

There are many built-in utility types in TypeScript, such as Partial, Required, etc. In this article, I introduce 7 common ones:

Let’s look at a few practical cases:

7. debounce

const debounce = <F extends (...args: any[]) => void>(
func: F,
ms: number,
) => {
let timeoutId: ReturnType<typeof setTimeout>;
return (...args: Parameters<F>) => {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func(...args);
}, ms);
};
};

8. throttle

const throttle = <F extends (...args: any[]) => void>(
func: F,
ms: number,
) => {
let last = 0;
return (...args: Parameters<F>) => {
const now = Date.now();
if (now - last < ms) return;
last = now;
func(...args);
};
};

9. Expands an array at the specified level

const flatten = <T = any>(arr: T[], depth = 1) => {
const ret: T[] = [];
for (const item of arr) {
if (depth > 0 && Array.isArray(item)) {
ret.push(...flatten(item, depth - 1));
} else {
ret.push(item);
}
}
return ret;
};

More ways to flatten arrays:

10. Automatically execute Generator and return final Promise

Similar to co.wrap.

Here is a test example:

Thanks for reading. If you like such stories and want to support me, please consider becoming a Medium member. It costs $5 per month and gives you unlimited access to Medium content. I’ll get a little commission if you sign up via my link.

Your support is very important to me — thank you.

--

--