Mohsen
Mohsen

Reputation: 812

TypeScript Generic Parameters

I am trying to make my log method to be generic. What I need as the main concept is as below:

class A {
    user_id: number;
    // and some other props...
}

class B {
    service_name: string;
    // and some other props...
}

function log<T>(...T parameters) {
    // logging the input parameters
}

log<A>(
    A.user_id = 123
);

log<B>(
    B.service_name = 'my_service_name';
);

What I have tried so far is as below, but I cannot make it working. I am doing this, because my project is getting bigger and more levels and entries would be added day-to-day.

enum levels {
    error,
    info,
}

enum entries {
    user_id,
    service_name,
}

function log(level: levels, ...entries: entries[]) {
    // perform the actual log...
}

log(
    levels.info,
    entries.user_id = 123
);

log(
    levels.error,
    entries.service_name = 'my_sevice_name'    
);

The reason that I have used enums in my example, is that I wanted to force the developer to choose a predefined value from a list and not to use magic numbers or magic strings.

Upvotes: 1

Views: 69

Answers (2)

cefn
cefn

Reputation: 3321

Is it as simple as using unions to define the keys?

type Level = "error" | "info"

type EntryKey = "user_id" | "service_name"

type Entry = Partial<{
  [K in EntryKey]:string
}>

function log(level: Level, ...entries: Entry[]) {
    // perform the actual log...
}

log("error", {service_name:"something"})

Upvotes: 2

MrCodingB
MrCodingB

Reputation: 2314

If you want your second solution to "work" you'd have to change the function calls to this:

enum levels {
    error,
    info,
}

interface entry {
    user_id,
    service_name,
}

function log(level: levels, ...entries: entry[]) {
    // perform the actual log...
}

log(
    levels.info,
    { user_id: 123 }
);

log(
    levels.error,
    { service_name: 'my_sevice_name' }
);

Upvotes: 1

Related Questions