Coder Social home page Coder Social logo

typescript-exercises / typescript-exercises Goto Github PK

View Code? Open in Web Editor NEW
2.8K 23.0 468.0 2.23 MB

A set of interactive TypeScript exercises

Home Page: https://typescript-exercises.github.io

License: MIT License

TypeScript 99.27% JavaScript 0.13% HTML 0.60%

typescript-exercises's Introduction

TypeScript exercises

Start your journey here: https://typescript-exercises.github.io/

The goal: Let everyone play with many different TypeScript features and get an overview of TypeScript capabilities and principles.

Sponsor me: https://github.com/sponsors/mdevils

Things to cover

  1. Basic typing.
  2. Refining types.
  3. Union types.
  4. Merged types.
  5. Generics.
  6. Type declarations.
  7. Module augmentation.
  8. Advanced type mapping.

Rules and principles

  1. Avoid using any type at all costs.

  2. Difficulty quickly grows one exercise after another.

  3. Feel free to send pull requests if you've come up with improvements!

  4. Provide feedback to the creator of these exercises.

  5. Enjoy.

Contributing

  1. Your contributions are welcome.

  2. yarn start starts the development server.

typescript-exercises's People

Contributors

24x7soumya avatar abraaoalves avatar alex-sh-wu avatar boraozenbirkan avatar bumprat avatar chaosmirage avatar cherryblossom000 avatar damasceno-dev avatar dependabot[bot] avatar everdimension avatar gessiomori avatar ianholden123 avatar imteekay avatar jbandi avatar jessevanassen avatar jhsorge avatar ketan-10 avatar kostasx avatar lucasguffroy59 avatar marcelgerber avatar mdevils avatar mithi avatar pvinis avatar rzvjerkovic avatar sauvejeanluc avatar seandlg avatar startswithaj avatar thedoctor0 avatar thoughtworks-tcaceres avatar uranium93 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typescript-exercises's Issues

exercise 7

hope all safe
I was able to resolve exercise 7 using Omit
but I am trying to resolve it in a different way using Exclude

type PowerUser = Exclude<User, 'type'> & Exclude<Admin, 'type'> & { type: 'userType' }

and this throwing error that :

Type '"powerUser"' is not assignable to type '"user" | "admin"'.ts(2322) index.ts(31, 5): The expected type comes from property 'type' which is declared here on type 'Person'

anyone can help to understand why type:'powerUser' in not in PowerUser type
thanks

Feedback

Thanks so much for these exercises! They're really useful.

I'd love if there were suggested solutions somewhere. I'm moderately experienced in Typescript, but self-taught; even if I can find a solution to the exercise, I often wonder if there's a "better way." It would be interesting to see the solution you came up with for the exercises.

Thank you again.

Problem with infer keyword and recursion

When using the infer keyword or a recursion in types we get a red highlight
in question 10 i want to use this ;

type strReverse<T extends string> = T extends `${infer A}${infer B}` ? `${strReverse<B>}${A}` : T;

but i get red highlights under infer and under the type name

Second exercise does`t pass the tests

At first, I completed the task on my own, but still got the errors. Then I opened the solution and just copy/pasted it into your editor, however the errors didn't go away.

Log?):
test.ts(5,5): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(12,5): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(19,5): error TS2344: Type 'false' does not satisfy the constraint 'true'.

Work together to improve the TS practice community

Hello dear developers @mdevils, I am ZLY201, the author of Js-sdsl.

Inspired by this project, I started a new similar project typescript-tutorial-exercises.

In order to allow TS enthusiasts to learn TS syntax more deeply, we need to provide a community with complete functions and friendly interface, just like LeetCode. I think that with the popularity and power of browsers, the stage and audience of this community will become more and more popular. getting bigger.

If possible I hope we can improve this project together and if necessary I can merge my organization into yours :).

Exercise 12: Suggestion solution does not account for `null` returns

According to the readme of the stats package, getMedianElement, getMinElement, ... may return null if the passed-in array is empty. However, the suggested solution declares them as follows

type GetElement = <T>(input: T[], comparator: Comparator<T>) => T ;
export const getMedianElement: GetElement;
export const getMinElement: GetElement;

I would argue that type GetElement = <T>(input: T[], comparator: Comparator<T>) => T | null; would be more correct. Sadly, this is not accepted as a solution.

Getting Started - Issue

Thanks for providing a great exercise curriculum! The one step that is missing is the npm i. It would be helpful, especially for beginners to clearly say in the README or in the first exercise to install deps. Thanks again!

Exercice 10-11: it's possible to provide awful type declarations

Hello,
I'm currently doing the exercises and loving it!

I however noticed a way to "hack" exercise 11, I can declare my module as such

declare module 'stats' {
  const getMaxIndex: Function;
  const getMinIndex: Function;
  const getMaxElement: Function;
  const getMinIndex: Function;
  const getMinElement: Function;
  const getMedianIndex: Function;
  const getMedianElement: Function;
  const getAverageValue: Function;
}

I'm not sure there's a way to prevent this or should be unallowed in the rules.

Thanks for your time

Minor copy changes and suggestions

Hi there,

Firstly, I loved working through these exercises, what a great repo and interactive tool you've built!

There are a few places where the English could be very slightly improved, and some grammatical errors. I've got a branch of copy suggestions ready, if you're willing to give me permission I'll open a PR.

Thanks again for the awesome repo!

Missing Return Statement in Exercise 14. Reduce Function

export function reduce(reducer, initialValue, input) {
    // .....
    if (arguments.length === 1) {
        return function subFunction(subInitialValue, subInput) {
            if (arguments.length === 0) {
                return subFunction;
            }
            if (arguments.length === 1) {
                return function subSubFunction(subSubInput) {
                    if (arguments.length === 0) {
                        return subSubFunction;
                    }
                    return input.reduce(reducer, subInitialValue);
                };
            }
        }
    }
    // .....
}

return function subFunction(subInitialValue, subInput) {

Missing return statement for subFunction, on all arguments are provided.
It Should be :

export function reduce(reducer, initialValue, input) {
    // .....
    if (arguments.length === 1) {
        return function subFunction(subInitialValue, subInput) {
            if (arguments.length === 0) {
                return subFunction;
            }
            if (arguments.length === 1) {
                return function subSubFunction(subSubInput) {
                    if (arguments.length === 0) {
                        return subSubFunction;
                    }
                    return input.reduce(reducer, subInitialValue);
                };
            }
            return subInput.reduce(reducer,subInitialValue);
        }
    }
    // .....
}

Feedback for exercises

Hello!

I streamed my solution process to twitch. In total, it took me around 3 hours I think.
I really enjoyed the exercises and had a lot of fun working on the harder ones.

As you asked for feedback in the README, here are some points:

  • Use a test runner for the tests right now, you only ever get one error message on the console and it is formatted quite poorly (it's just stringified on the console). Something like jest would better show you the results and the percentage of passed/failing tests.
  • More granular tests that is regarding exercises 13,14 and 15. I completed 14 with some bugs left in the sort options. More fine grained tests, testing all features of the interface would prevent these problems
  • Add tests for types with several TypeScript helper functions, you could add tests for the types itself, so that return types could be better checked. See this article for reference: https://2ality.com/2019/07/testing-static-types.html
  • type safety for the projection field: We could get better type safety when we change the interface from receiving and object with "1" in all keys that we want to retain, to an array of keys. That way we could use the "Pick" type to return the reduced type from the find method. I tried implementing that with the current interface but could not get that working.

As I said, I hat lots of fun during this challenge! Huge props to you :)

Best regards.

How does exercise 10 solution work?

type CallbackBasedAsyncFunction<X> = (callback: (response: ApiResponse<X>) => void) => void;
...
type SourceObject<T> = {[K in keyof T]: CallbackBasedAsyncFunction<T[K]>};

And this is the SourceObject,

const oldApi = {
    requestAdmins: (callback: (response: ApiResponse<Admin[]>) => void) => {
        callback({
            status: 'success',
            data: admins
        });
    },

My understanding is that here,
T[K] - (callback: ...) => { ...}
If this is being passed to PromiseBasedAsyncFunction, then
X in PromiseBasedAsyncFunction is (callback: ...) => { ...}.

But how is X interpreted to be Admin[] instead?

Cannot collapse side menu or error section

I'm having trouble collapsing the side menu and error section on typescript-exercises.github.io. I tried clicking on the highlighted buttons but it didn't work.
image

Browser: Version 106.0.5249.91 on MacOS Ventura (Incognito)

Exercise 7 typing issue

My solution:

type PowerUser = Omit<User, "type"> &
  Omit<Admin, "type"> & { type: "powerUser" };

Official solution:

type PowerUser = Omit<User & Admin, 'type'> & {
    type: 'powerUser'
};

TypeScript 3.9 made changes to advanced types and the official solution will error out on >=3.9. I'd suggest the solutions branch to utilize this new recommendation.

Confused about alternate solution for exercice 8

The recommended solution for exercice 8 is to write :

type PowerUser = Omit<User, 'type'> & Omit<Admin, 'type'> & {
    type: 'powerUser'
};

I had written this solution, which seems more DRY and works in the online game

type PowerUser = Omit<User & Admin, "type"> & {
   type: "powerUser"
};

So i tried to submit it as a pull request, but i'm unable to get it to work locally.
The compiler is interpreting PowerUser as

Pick<never, string|number|symbol> & {
   type:"powerUser"
};

I then figured out that type of User & Admin is never because they have no intersection (type can't be both "user" and "admin" at the same time), so Typescript is in fact clever here.

But then why is the online game accepting my solution ? Is it TS version specific ? If so, shouldn't the compiler used be upgraded ?

Typo in exercise 14

export function subtract(a, b) {
    if (arguments.length === 0) {
        return add;
    }
    if (arguments.length === 1) {
        return function subFunction(subB) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return a - subB;
        };
    }

It should be return subtract when arguments.length === 0

tsconfig.json 'esModuleInterop'

in exercise, we use import chalk from 'chalk'
but this module use commonJS, VSCode warning this problem

we need add this compilerOptions

{
  "compilerOptions": {
    // ...
    "esModuleInterop": true,
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.