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
tsTry
typeFirstLetter <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
tsTry
typeTypeExtends <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
tsTry
typePets = "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>>]