Type challenges are a great way to practice using the TS type system. These are often quite challenging, but they give you valuable practice thinking about how utility types work.
Let’s tackle a curated selection of these challenges ourselves!
Round 1
If<C, T, F>
Implement a type that evaluates to T if the type C is
true or F if C is false.
tsTry// Implement this typetypeIf <C ,T ,F > = never// Teststypecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <If <true, "apple", "pear">, "apple">>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <If <false, "orange", 42>, 42>>]
LengthOfTuple<T>
Implement a type that evaluates to a numeric type literal, equivalent to the
length of a specified tuple type T
tsTry// Implement this typetypeLengthOfTuple <T > = never// TestsconstFruits = ["cherry", "banana"] asconst typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <LengthOfTuple <[1, 2, 3]>, 3>>,Expect <NotEqual <LengthOfTuple <[1, 2, 3]>, 2>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <LengthOfTuple <typeofFruits >, 2>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <LengthOfTuple <[]>, 0>>]
EndsWith<A, B>
Implement a type that evaluates to true if the type A ends with the type B,
otherwise false.
tsTry// Implement this typetypeEndsWith <A ,B > = any// Teststypecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <EndsWith <"ice cream", "cream">, true>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <EndsWith <"ice cream", "chocolate">, false>>]
Click for hints
tsTrytypeFirstLetter <S > =S extends `${inferF }${string}`?F : neverletfirstLetterOfBird :FirstLetter <"bird">letfirstLetterOfDog :FirstLetter <"dog">
Concat<A, B>
Implement a type that concatenates two tuple types A, and B
tsTry// Implement this typetypeConcat <A ,B > = any// Teststypecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <Concat <[], []>, []>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <Concat <[], ["hello"]>, ["hello"]>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <Concat <[18, 19], [20, 21]>, [18, 19, 20, 21]>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <Concat <[42, "a", "b"], [Promise <boolean>]>,[42, "a", "b",Promise <boolean>]>>]
Round 2
ReturnOf<F>
Implement a type that emits the return type of a function type F
tsTry// Implement this typetypeReturnOf <F > = never// TestsconstflipCoin = () =>Math .random () > 0.5 ? "heads" : "tails"constrockPaperScissors = (arg : 1 | 2 | 3) => {returnarg === 1? ("rock" asconst ):arg === 2? ("paper" asconst ): ("scissors" asconst )}typecases = [// simple 1Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <boolean,ReturnOf <() => boolean>>>,// simple 2Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <123,ReturnOf <() => 123>>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <ComplexObject ,ReturnOf <() =>ComplexObject >>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <Promise <boolean>,ReturnOf <() =>Promise <boolean>>>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <() => "foo",ReturnOf <() => () => "foo">>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <"heads" | "tails",ReturnOf <typeofflipCoin >>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <"rock" | "paper" | "scissors",ReturnOf <typeofrockPaperScissors >>>]typeComplexObject = {a : [12, "foo"]bar : "hello"prev (): number}
Split<S, SEP>
Implement a type that splits a string literal type S by a delimiter SEP, emitting
a tuple type containing the string literal types for all of the “tokens”
tsTry// Implement this typetypeSplit <S extends string,SEP extends string> = any// Teststypecases = [Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <Split <"Hi! How are you?", "z">,["Hi! How are you?"]>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <Split <"Hi! How are you?", " ">,["Hi!", "How", "are", "you?"]>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <Split <"Hi! How are you?", "">,["H","i","!"," ","H","o","w"," ","a","r","e"," ","y","o","u","?"]>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <Split <"", "">, []>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <Split <"", "z">, [""]>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <Split <string, "whatever">, string[]>>]
IsTuple<T>
Implement a type IsTuple, which takes an input type T and returns whether
T is tuple type.
tsTry// Implement this typetypeIsTuple <T > = any// Teststypecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IsTuple <[]>, true>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IsTuple <[number]>, true>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IsTuple <readonly [1]>, true>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IsTuple <{length : 1 }>, false>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IsTuple <number[]>, false>>]
Click for hints
tsTrytypeTypeExtends <A ,B > =A extendsB ? true : falselett0 :TypeExtends <number, 6>lett1 :TypeExtends <6, number>
Round 3
TupleToNestedObject<P, V>
Given a tuple type T that only contains string type, and a type U,
build an object recursively.
tsTry// Implement this typetypeTupleToNestedObject <P ,V > = any// Teststypecases = [Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <TupleToNestedObject <["a"], string>, {a : string }>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <TupleToNestedObject <["a", "b"], number>,{a : {b : number } }>>,Expect <Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Equal <TupleToNestedObject <["a", "b", "c"], boolean>,{a : {b : {c : boolean } } }>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <TupleToNestedObject <[], boolean>, boolean>>]
Click for hints
tsTrytypePets = "dog"typePetsObj = {[K inPets ]:Promise <number>}letx :PetsObj
IndexOf<T, U>
Implement the type version of Array.indexOf, IndexOf<T, U>
takes an Array T, any U and returns the index of the first U in Array T.
tsTry// Implement this typetypeIndexOf <T ,U > = any// Teststypecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IndexOf <[1, 2, 3], 2>, 1>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IndexOf <[2, 6, 3, 8, 4, 1, 7, 3, 9], 3>, 2>>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <IndexOf <[0, 0, 0], 2>, -1>>]