Convert Figma logo to code with AI

type-challenges logotype-challenges

Collection of TypeScript type challenges with online judge

42,414
4,602
42,414
30,251

Top Related Projects

100,112

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

:books: The definitive guide to TypeScript and possibly the best TypeScript book :book:. Free and Open Source 🌹

44,903

Cheatsheets for experienced React developers getting started with TypeScript

An interactive TypeScript tutorial for beginners

13,967

A collection of essential TypeScript types

Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).

Quick Overview

Type Challenges is a collection of TypeScript type puzzles designed to help developers improve their TypeScript skills. It offers a wide range of challenges, from beginner to advanced levels, focusing on type manipulation and advanced TypeScript features.

Pros

  • Provides hands-on practice for TypeScript type system
  • Covers a wide range of difficulty levels, suitable for beginners to experts
  • Encourages community contributions and discussions
  • Regularly updated with new challenges

Cons

  • May be overwhelming for complete beginners to TypeScript
  • Some challenges can be highly complex and theoretical
  • Limited practical application for certain advanced challenges
  • Requires a solid understanding of TypeScript to fully benefit

Code Examples

  1. Easy challenge: Pick
// Implement the built-in Pick<T, K> generic without using it.
type MyPick<T, K extends keyof T> = {
  [P in K]: T[P];
};
  1. Medium challenge: Promise.all
// Type the function PromiseAll that accepts an array of PromiseLike objects, the returning value should be Promise<T> where T is the resolved result array.
declare function PromiseAll<T extends any[]>(
  values: readonly [...T]
): Promise<{ [K in keyof T]: T[K] extends PromiseLike<infer R> ? R : T[K] }>;
  1. Hard challenge: Currying
// Implement the type version of currying.
type Curry<F> = F extends (...args: infer A) => infer R
  ? A extends [infer First, ...infer Rest]
    ? (arg: First) => Curry<(...args: Rest) => R>
    : R
  : never;

Getting Started

  1. Visit the Type Challenges repository
  2. Choose a challenge based on your skill level (Easy, Medium, Hard, or Extreme)
  3. Open the challenge in the TypeScript Playground or your local development environment
  4. Implement the type as requested in the challenge description
  5. Run the provided test cases to verify your solution
  6. Compare your solution with others or discuss in the comments section

Competitor Comparisons

100,112

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

Pros of TypeScript

  • Official repository for the TypeScript language, providing the most up-to-date and authoritative source code
  • Comprehensive documentation, including language specification, release notes, and roadmap
  • Active development with frequent updates and bug fixes

Cons of TypeScript

  • Larger codebase, which may be overwhelming for beginners or those looking to contribute
  • Focus on language implementation rather than learning exercises or challenges
  • Less emphasis on community-driven content and problem-solving

Code Comparison

TypeScript (compiler implementation):

function createDiagnostic(node: Node, message: DiagnosticMessage, ...args: any[]): DiagnosticWithLocation {
    const diagnostic = createDiagnosticForNode(node, message, ...args);
    return diagnostic;
}

Type Challenges (example challenge):

type HelloWorld = string // expected to be a string

Summary

TypeScript is the official repository for the TypeScript language, offering comprehensive documentation and frequent updates. However, it may be overwhelming for beginners and lacks focus on learning exercises. Type Challenges, on the other hand, provides a collection of TypeScript type challenges for learning and practice, with a more community-driven approach. The code comparison illustrates the difference in focus, with TypeScript showing language implementation details and Type Challenges presenting concise learning exercises.

:books: The definitive guide to TypeScript and possibly the best TypeScript book :book:. Free and Open Source 🌹

Pros of typescript-book

  • Comprehensive learning resource covering TypeScript concepts and best practices
  • Structured content with clear explanations and examples
  • Suitable for beginners and intermediate developers

Cons of typescript-book

  • Less hands-on practice compared to type-challenges
  • May not cover advanced type manipulation techniques as extensively
  • Static content that may not be updated as frequently as community-driven challenges

Code Comparison

typescript-book example:

interface Person {
  name: string;
  age: number;
}

function greet(person: Person) {
  return `Hello, ${person.name}!`;
}

type-challenges example:

type HelloWorld<T> = T extends string ? `Hello, ${T}!` : never;

// Expected: "Hello, World!"
type result = HelloWorld<'World'>;

The typescript-book example demonstrates basic interface and function typing, while the type-challenges example showcases advanced type manipulation using conditional types and template literal types.

typescript-book provides a more traditional learning approach with explanations and examples, while type-challenges offers hands-on practice with increasingly complex type puzzles. Both repositories serve different purposes in the TypeScript learning ecosystem, with typescript-book being more suitable for beginners and type-challenges catering to those looking to deepen their understanding of TypeScript's type system.

44,903

Cheatsheets for experienced React developers getting started with TypeScript

Pros of react

  • Focuses specifically on React and TypeScript integration
  • Provides practical, real-world examples and best practices
  • Offers a comprehensive cheatsheet format for quick reference

Cons of react

  • Less emphasis on advanced TypeScript concepts
  • May not cover as wide a range of TypeScript challenges
  • Could become outdated as React and TypeScript evolve

Code Comparison

type-challenges:

type HelloWorld = string
type test = Expect<Equal<HelloWorld, string>>

react:

interface Props {
  name: string;
  age: number;
}

const MyComponent: React.FC<Props> = ({ name, age }) => {
  return <div>{name} is {age} years old</div>;
}

The type-challenges example focuses on pure TypeScript type manipulation, while the react example demonstrates practical TypeScript usage within a React component.

type-challenges offers a wide range of TypeScript puzzles and challenges, helping users deepen their understanding of the language's type system. It's excellent for honing advanced TypeScript skills and exploring edge cases.

react, on the other hand, provides a more applied approach, focusing on how to effectively use TypeScript in React projects. It offers guidelines, patterns, and best practices specific to React development with TypeScript.

Both repositories serve different purposes and can be complementary in a developer's learning journey. type-challenges is ideal for mastering TypeScript's type system, while react is more suitable for practical application in React projects.

An interactive TypeScript tutorial for beginners

Pros of beginners-typescript-tutorial

  • More beginner-friendly, with a structured learning path
  • Includes video tutorials for visual learners
  • Focuses on practical, real-world TypeScript usage

Cons of beginners-typescript-tutorial

  • Less comprehensive coverage of advanced TypeScript features
  • Fewer challenges overall, limiting practice opportunities
  • May not be as suitable for experienced TypeScript developers

Code Comparison

beginners-typescript-tutorial:

interface User {
  id: number;
  name: string;
  email: string;
}

function getUserInfo(user: User): string {
  return `${user.name} (${user.email})`;
}

type-challenges:

type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type Result = GetReturnType<() => string>; // Result is string
type ComplexResult = GetReturnType<(a: number, b: string) => boolean>; // ComplexResult is boolean

Summary

beginners-typescript-tutorial is ideal for newcomers to TypeScript, offering a structured approach with video content and focusing on practical applications. However, it may not delve as deeply into advanced topics as type-challenges.

type-challenges provides a more comprehensive set of challenges, covering a wider range of TypeScript features and complexities. It's better suited for developers looking to push their TypeScript skills to the limit, but may be overwhelming for beginners.

Choose based on your current TypeScript proficiency and learning goals.

13,967

A collection of essential TypeScript types

Pros of Type Fest

  • Type Fest provides a comprehensive collection of commonly used TypeScript types, making it a valuable resource for developers.
  • The library is actively maintained and regularly updated, ensuring compatibility with the latest TypeScript versions.
  • Type Fest includes a wide range of utility types, such as Awaited, Promisable, and Primitive, which can save developers time and effort.

Cons of Type Fest

  • Type Fest may be overkill for smaller projects that only require a few specific types.
  • The library can be more difficult to navigate compared to the more focused Type Challenges repository.
  • Some developers may prefer to create their own custom types rather than relying on a third-party library.

Code Comparison

Type Challenges:

type Includes<T extends readonly any[], U> = T extends [infer F, ...infer R]
  ? Equal<F, U> extends true
    ? true
    : Includes<R, U>
  : false;

Type Fest:

type Includes<T extends readonly any[], U> = T extends [infer F, ...infer R]
  ? Equal<F, U> extends true
    ? true
    : Includes<R, U>
  : false;

As you can see, the implementation of the Includes type is very similar between the two repositories, demonstrating the overlap in the types they provide.

Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).

Pros of utility-types

  • Ready-to-use utility types for immediate implementation in projects
  • Comprehensive documentation with examples for each utility type
  • Actively maintained with regular updates and improvements

Cons of utility-types

  • Less focus on learning and understanding complex type manipulations
  • Fewer community contributions and discussions compared to type-challenges
  • May lead to over-reliance on pre-built utilities instead of custom solutions

Code Comparison

type-challenges:

// Implement a type that adds two numbers
type Add<A extends number, B extends number> = [
  ...TupleOf<A>, ...TupleOf<B>
]['length'];

utility-types:

// Pre-defined utility type for non-nullable types
type NonNullable<T> = T extends null | undefined ? never : T;

Summary

type-challenges focuses on learning and practicing advanced TypeScript concepts through challenges, fostering a deeper understanding of the type system. It encourages community engagement and problem-solving skills.

utility-types provides a collection of ready-made utility types for immediate use in projects. It offers well-documented, practical solutions but may not emphasize the learning aspect as much as type-challenges.

Choose type-challenges for improving TypeScript skills and understanding complex type manipulations. Opt for utility-types when seeking efficient, pre-built solutions for common type scenarios in projects.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Collection of TypeScript type challenges


English | 简体中文 | 日本語 | 한국어 | Português

Intro

by the power of TypeScript's well-known Turing Completed type system

High-quality types can help improve projects' maintainability while avoiding potential bugs.

There are a bunch of awesome type utility libraries that may boost your works on types, like ts-toolbelt, utility-types, SimplyTyped, etc., which you can already use.

This project is aimed at helping you better understand how the type system works, writing your own utilities, or just having fun with the challenges. We are also trying to form a community where you can ask questions and get answers you have faced in the real world - they may become part of the challenges!

Challenges

Click the following badges to see details of the challenges.

Note: Challenges work in the strict mode.


1
13・Hello World

13
4・Pick 7・Readonly 11・Tuple to Object 14・First of Array 18・Length of Tuple 43・Exclude 189・Awaited 268・If 533・Concat 898・Includes 3057・Push 3060・Unshift 3312・Parameters

98
2・Get Return Type 3・Omit 8・Readonly 2 9・Deep Readonly 10・Tuple to Union 12・Chainable Options 15・Last of Array 16・Pop 20・Promise.all 62・Type Lookup 106・Trim Left 108・Trim 110・Capitalize 116・Replace 119・ReplaceAll 191・Append Argument 296・Permutation 298・Length of String 459・Flatten 527・Append to object 529・Absolute 531・String to Union 599・Merge 612・KebabCase 645・Diff 949・AnyOf 1042・IsNever 1097・IsUnion 1130・ReplaceKeys 1367・Remove Index Signature 1978・Percentage Parser 2070・Drop Char 2257・MinusOne 2595・PickByType 2688・StartsWith 2693・EndsWith 2757・PartialByKeys 2759・RequiredByKeys 2793・Mutable 2852・OmitByType 2946・ObjectEntries 3062・Shift 3188・Tuple to Nested Object 3192・Reverse 3196・Flip Arguments 3243・FlattenDepth 3326・BEM style string 3376・InorderTraversal 4179・Flip 4182・Fibonacci Sequence 4260・AllCombinations 4425・Greater Than 4471・Zip 4484・IsTuple 4499・Chunk 4518・Fill 4803・Trim Right 5117・Without 5140・Trunc 5153・IndexOf 5310・Join 5317・LastIndexOf 5360・Unique 5821・MapTypes 7544・Construct Tuple 8640・Number Range 8767・Combination 8987・Subsequence 9142・CheckRepeatedChars 9286・FirstUniqueCharIndex 9616・Parse URL Params 9896・GetMiddleElement 9898・Appear only once 9989・Count Element Number To Object 10969・Integer 16259・ToPrimitive 17973・DeepMutable 18142・All 18220・Filter 21104・FindAll 21106・Combination key type 21220・Permutations of Tuple 25170・Replace First 25270・Transpose 26401・JSON Schema to TypeScript 27133・Square 27152・Triangular number 27862・CartesianProduct 27932・MergeAll 27958・CheckRepeatedTuple 28333・Public Type 29650・ExtractToObject 29785・Deep Omit 30301・IsOdd 30430・Tower of hanoi 30958・Pascal's triangle 30970・IsFixedStringLiteralType 34007・Compare Array Length

53
6・Simple Vue 17・Currying 1 55・Union to Intersection 57・Get Required 59・Get Optional 89・Required Keys 90・Optional Keys 112・Capitalize Words 114・CamelCase 147・C-printf Parser 213・Vue Basic Props 223・IsAny 270・Typed Get 300・String to Number 399・Tuple Filter 472・Tuple to Enum Object 545・printf 553・Deep object to unique 651・Length of String 2 730・Union to Tuple 847・String Join 956・DeepPick 1290・Pinia 1383・Camelize 2059・Drop String 2822・Split 2828・ClassPublicKeys 2857・IsRequiredKey 2949・ObjectFromEntries 4037・IsPalindrome 5181・Mutable Keys 5423・Intersection 6141・Binary to Decimal 7258・Object Key Paths 8804・Two Sum 9155・ValidDate 9160・Assign 9384・Maximum 9775・Capitalize Nest Object Keys 13580・Replace Union 14080・FizzBuzz 14188・Run-length encoding 15260・Tree path array 19458・SnakeCase 25747・IsNegativeNumber 28143・OptionalUndefined 30178・Unique Items 30575・BitwiseXOR 31797・Sudoku 31824・Length of String 3 32427・Unbox 32532・Binary Addition 34286・Take Elements

17
5・Get Readonly Keys 151・Query String Parser 216・Slice 274・Integers Comparator 462・Currying 2 476・Sum 517・Multiply 697・Tag 734・Inclusive Range 741・Sort 869・DistributeUnions 925・Assert Array Index 6228・JSON Parser 7561・Subtract 31447・CountReversePairs 31997・Parameter Intersection 33345・Dynamic Route

By Tags
#JSON26401・JSON Schema to TypeScript
#application12・Chainable Options 8767・Combination 6・Simple Vue 213・Vue Basic Props 30178・Unique Items
#arguments191・Append Argument 3196・Flip Arguments
#array14・First of Array 533・Concat 898・Includes 3057・Push 3060・Unshift 15・Last of Array 16・Pop 20・Promise.all 459・Flatten 949・AnyOf 3062・Shift 3243・FlattenDepth 4425・Greater Than 5117・Without 5153・IndexOf 5310・Join 5317・LastIndexOf 5360・Unique 8767・Combination 18142・All 18220・Filter 25270・Transpose 27133・Square 27152・Triangular number 27932・MergeAll 30430・Tower of hanoi 30958・Pascal's triangle 34007・Compare Array Length 17・Currying 1 2822・Split 5423・Intersection 8804・Two Sum 9160・Assign 9384・Maximum 9775・Capitalize Nest Object Keys 14080・FizzBuzz 31797・Sudoku 32427・Unbox 32532・Binary Addition 34286・Take Elements 216・Slice 734・Inclusive Range 741・Sort 925・Assert Array Index 31997・Parameter Intersection
#built-in4・Pick 7・Readonly 43・Exclude 189・Awaited 3312・Parameters 2・Get Return Type 3・Omit
#cif30178・Unique Items
#conditional type21220・Permutations of Tuple
#deep9・Deep Readonly 17973・DeepMutable 553・Deep object to unique 956・DeepPick
#filter18220・Filter
#function32427・Unbox
#game31797・Sudoku
#infer3312・Parameters 2・Get Return Type 10・Tuple to Union 2070・Drop Char 4260・AllCombinations 9616・Parse URL Params 55・Union to Intersection 57・Get Required 59・Get Optional 399・Tuple Filter 730・Union to Tuple 2059・Drop String 14080・FizzBuzz 734・Inclusive Range 741・Sort
#intersection31997・Parameter Intersection
#json6228・JSON Parser
#map62・Type Lookup 5821・MapTypes
#math529・Absolute 2257・MinusOne 25270・Transpose 27133・Square 27152・Triangular number 30958・Pascal's triangle 6141・Binary to Decimal 8804・Two Sum 14080・FizzBuzz 274・Integers Comparator 476・Sum 517・Multiply
#number25747・IsNegativeNumber
#object599・Merge 645・Diff 2595・PickByType 2757・PartialByKeys 2759・RequiredByKeys 2852・OmitByType 2946・ObjectEntries 3188・Tuple to Nested Object 3376・InorderTraversal 4179・Flip 5821・MapTypes 27932・MergeAll 29650・ExtractToObject 2949・ObjectFromEntries 9160・Assign 9775・Capitalize Nest Object Keys
#object-keys7・Readonly 11・Tuple to Object 8・Readonly 2 9・Deep Readonly 527・Append to object 1130・ReplaceKeys 1367・Remove Index Signature 2793・Mutable 28333・Public Type 7258・Object Key Paths 5・Get Readonly Keys
#omit object-keys deep29785・Deep Omit
#optional31997・Parameter Intersection
#parameters31997・Parameter Intersection
#promise189・Awaited 20・Promise.all 32427・Unbox
#readonly7・Readonly 8・Readonly 2 9・Deep Readonly 2793・Mutable 17973・DeepMutable
#recursion21220・Permutations of Tuple 34007・Compare Array Length 1383・Camelize 32532・Binary Addition
#rest31997・Parameter Intersection
#split2822・Split
#string531・String to Union 8767・Combination 9142・CheckRepeatedChars 9286・FirstUniqueCharIndex 9616・Parse URL Params 21104・FindAll 30301・IsOdd 2822・Split 4037・IsPalindrome 19458・SnakeCase
#template literal25747・IsNegativeNumber
#template-literal106・Trim Left 108・Trim 110・Capitalize 116・Replace 119・ReplaceAll 298・Length of String 529・Absolute 612・KebabCase 1978・Percentage Parser 2070・Drop Char 2688・StartsWith 2693・EndsWith 3326・BEM style string 4260・AllCombinations 4803・Trim Right 5140・Trunc 9616・Parse URL Params 10969・Integer 21104・FindAll 112・Capitalize Words 114・CamelCase 147・C-printf Parser 270・Typed Get 300・String to Number 472・Tuple to Enum Object 545・printf 651・Length of String 2 2059・Drop String 19458・SnakeCase 151・Query String Parser 274・Integers Comparator 476・Sum 517・Multiply 6228・JSON Parser
#this6・Simple Vue 1290・Pinia
#tuple18・Length of Tuple 3312・Parameters 10・Tuple to Union 3188・Tuple to Nested Object 3192・Reverse 3326・BEM style string 4471・Zip 4484・IsTuple 4499・Chunk 4518・Fill 7544・Construct Tuple 21220・Permutations of Tuple 27133・Square 27152・Triangular number 399・Tuple Filter 472・Tuple to Enum Object 730・Union to Tuple 2822・Split 30178・Unique Items 31797・Sudoku 32427・Unbox 7561・Subtract
#union4・Pick 43・Exclude 3・Omit 10・Tuple to Union 62・Type Lookup 296・Permutation 531・String to Union 1042・IsNever 1097・IsUnion 3326・BEM style string 4260・AllCombinations 5117・Without 8987・Subsequence 9142・CheckRepeatedChars 21220・Permutations of Tuple 27862・CartesianProduct 27932・MergeAll 730・Union to Tuple 1383・Camelize 5423・Intersection 31797・Sudoku
#utils268・If 1042・IsNever 5821・MapTypes 55・Union to Intersection 57・Get Required 59・Get Optional 89・Required Keys 90・Optional Keys 223・IsAny 270・Typed Get 2828・ClassPublicKeys 2857・IsRequiredKey 5181・Mutable Keys 32427・Unbox 5・Get Readonly Keys
#variadic31997・Parameter Intersection
#vue6・Simple Vue 213・Vue Basic Props 1290・Pinia
          

By Plain Text

warm-up (1)

easy (13)

medium (98)

hard (53)

extreme (17)


✨ Upcoming challenges

🔥 Start the challenge in TypeScript Playground

🚀 Start the challenge locally in your IDE or text editor with TypeScript language support

⚡️ Start the challenge in VS Code Extension

Recommended Readings

Official

Articles

Talks

Projects / Solutions

Books

How to Contribute

There are several ways you can contribute to this project

  • Share your answers / solutions
  • Propose new challenges
  • Add more test cases to the existing challenges
  • Provide learning resources or ideas of how to solve challenges
  • Share the problems you have faced in real-world projects, regardless you having the solution or not - the community would help you as well
  • Help with others by discussion in issues
  • Contribute the infra of this project TODOs.md

Just open an issue and choose the corresponding template. Thanks!

Play Locally

You can build the challenges and play locally using your preferred IDE or text editor with TypeScript language support.

To do that, you will need the latest version of Node.js and pnpm installed.

After cloning the repo, installed the dependencies by:

pnpm install

Then and run the generate script:

pnpm generate

It will prompt you to select the desired language, then you can find the generated challenges in the ./playground folder.

Later if you want to update playground while keeping your changes:

pnpm generate --keep-changes

OR

pnpm generate -K

Thanks

This project was born from solving real-world types problem with @hardfist and @MeCKodo. And great thanks to @sinoon who contributed a lot while giving early feedback on this project.

Inspired by

Contributors

Contributors

License

MIT