0

Consider the following interfaces:

export interface FooInterface<T, O extends FooOptions<T>> {
  items: T[];
  options: O;
}

interface FooOptions<T> {
  doSomething: (e: T) => void;
}

Now whenever i need to do something with this I need to repeat T. For example:

const t: FooInterface<string, FooOptions<string>> = {
  items: ["a","b","c"],
  options: {doSomething: (e) => {
      console.log(e);
  }}
}

Now, repeating is boring, is it possible to create a type or interface where T should be string for both types, or redefine the interfaces somehow, so that I write something like this instead:

const t: FooInterfaceString
//or
const t: FooInterfaceOfType<string>

3 Answers 3

2

The other answers here are correct, but I want to add that you might consider using generic parameter defaults if you are usually (but not always) going to just pass in FooOptions<T> as the type of O:

interface FooOptions<T> {
    doSomething: (e: T) => void;
}

// note how O has a default value now
export interface FooInterface<T, O extends FooOptions<T> = FooOptions<T>> {
    items: T[];
    options: O;
}

That lets you just leave out the O parameter when you intend it to just be FooOptions<T>:

const t: FooInterface<string> = {
    items: ["a", "b", "c"],
    options: {
        doSomething: (e) => {
            console.log(e);
        }
    }
}

And in the event that you actually want O to be more specific than FooOptions<T> (that's why you have it as a separate parameter, right?), you can still do it:

interface MoreOptions {
    doSomething: (e: string) => void;
    doNothing: () => void;
}

const u: FooInterface<string, MoreOptions> = {
    items: ["d", "e", "f"],
    options: {
        doSomething(e) { console.log(e); },
        doNothing() { console.log("lol nvm"); }
    }
}

Oh, and if T will usually be string then you can add a default for it too and then FooInterface without parameters will be interpreted as FooInterface<string, FooOptions<string>>:

export interface FooInterface<T = string, O extends FooOptions<T> = FooOptions<T>> {
    items: T[];
    options: O;
}

const t: FooInterface = {
    items: ["a", "b", "c"],
    options: {
        doSomething: (e) => {
            console.log(e);
        }
    }
}

Okay, hope that helps. Good luck!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a bunch, this was really exactly what I was looking for.
2

how about :

type FooInterfaceString = FooInterface<string, FooOptions<string>>;

also, maybe consider this if it fits your design:

export interface FooInterface<T> {
  items: T[];
  options: FooOptions<T>;
}
type FooInterfaceString = FooInterface<string>;

Comments

1

You could use a TypeScript alias:

// Declaration
type FooInterfaceOfType<T> = FooInterface<T, FooOptions<T>>;

// Usage
const t: FooInterfaceOfType<string>;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.