Skip to content

Instantly share code, notes, and snippets.

@M-Bekheet
Last active January 12, 2023 20:00
Show Gist options
  • Save M-Bekheet/a4b88c35ba86a88f312fd0c8994d356f to your computer and use it in GitHub Desktop.
Save M-Bekheet/a4b88c35ba86a88f312fd0c8994d356f to your computer and use it in GitHub Desktop.

Revisions

  1. M-Bekheet revised this gist Jan 12, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Generics.ts
    Original file line number Diff line number Diff line change
    @@ -44,7 +44,7 @@ set.add(1);

    const addIdToObject = <T>(obj: T) => ({ ...obj, id: 3 });

    const student = addIdToObject({ name: "Mahmoud", age: 26 });
    const student = addIdToObject({ name: "Jack", age: 32 });

    /*
    *
  2. M-Bekheet created this gist Jan 12, 2023.
    126 changes: 126 additions & 0 deletions Generics.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,126 @@
    // Generics

    /*
    *
    ===> Ex1
    *
    */

    type G1<S> = {
    data: S;
    };

    type E1 = G1<string>;
    type E2 = G1<{ firstName: string }>;

    /*
    *
    ===> Ex2: With Functions
    *
    */

    const makeFetch = <TData>(url: string): Promise<TData> =>
    fetch(url).then((res) => res.json());

    const students = makeFetch<string[]>("/students");
    const count = makeFetch<{ count: number }>("/count");

    /*
    *
    ===> Ex3: You can use generics with JS Set
    *
    */

    const set = new Set<number>();

    set.add(1);
    // set.add("text") //error

    /*
    *
    ===> Ex4: Inferring types (notice the addition of the id type)
    *
    */

    const addIdToObject = <T>(obj: T) => ({ ...obj, id: 3 });

    const student = addIdToObject({ name: "Mahmoud", age: 26 });

    /*
    *
    ===> Ex5: ReturnType & Awaited
    *
    */

    //we extends a function as ReturnType only works on functions so we tell TS that T type is a function
    type Result<T extends (...args: any) => any> = ReturnType<T>;
    type Res = Result<() => "Hello">;

    type Result2<T> = Awaited<Promise<T>>;
    type Res2 = Result2<number>;

    //both together
    type GetPromiseReturnType<T extends (...args: any) => any> = Awaited<
    ReturnType<T>
    >;

    type Result3 = GetPromiseReturnType<() => Promise<{ firstName: string }>>;

    /*
    *
    ===> Ex6: Add function constraint
    *
    */

    // Record: set object with constraint types (string, number, ...)
    const getHighestValue = <TObj extends Record<string, number>>(
    obj: TObj
    ): {
    key: keyof TObj;
    value: number;
    } => {
    const keys = Object.keys(obj);
    let key = keys[0];
    let highest = obj[keys[0]];

    for (const item of keys) {
    if (obj[item] > highest) {
    highest = obj[item];
    key = item;
    }
    }

    return { key, value: highest };
    };

    const pair = getHighestValue({
    a: 1,
    b: 2,
    c: 3,
    // d: false /==> error
    });

    /*
    *
    ===> Ex7: constraint a return type to a specific key of enumerable
    *
    */

    const getValue = <TObj, TKey extends keyof TObj>(obj: TObj, key: TKey) => {
    return obj[key];
    };

    const val = getValue({ a: 1, b: true, c: "text" }, "c");

    /*
    *
    ===> Ex8: defaults in type arguments
    *
    */

    const createSet = <T = string>() => new Set<T>();
    const set1 = createSet<number>();
    const set2 = createSet<[]>();
    const set3 = createSet(); // using the default string argument

    export {};