Как создать определенный псевдоним на основе универсального машинописного интерфейса - PullRequest
0 голосов
/ 02 мая 2019

Рассмотрим следующие интерфейсы:

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

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

Теперь, когда мне нужно что-то сделать с этим, мне нужно повторить T. Например:

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

Теперь повторять скучно,Можно ли создать тип или интерфейс, где T должен быть строкой для обоих типов, или как-то переопределить интерфейсы, чтобы я написал вместо этого что-то вроде этого:

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

Ответы [ 3 ]

2 голосов
/ 02 мая 2019

Другие ответы здесь верны, но я хочу добавить, что вы можете рассмотреть возможность использования универсальных параметров по умолчанию , если вы обычно (но не всегда) просто передаете FooOptions<T> в качестве типа 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;
}

Это позволяет вам просто пропустить параметр O, когда вы намереваетесь установить значение FooOptions<T>:

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

И в том случае, если вы действительно хотите, чтобы O был более конкретным, чем FooOptions<T> (вот почему он у вас есть в качестве отдельного параметра, верно?), Вы все равно можете сделать это:

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"); }
    }
}

О, и если T обычно будет string, тогда вы можете добавить для него значение по умолчанию, и тогда FooInterface без параметров будет интерпретироваться как 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);
        }
    }
}

Хорошо, надеюсь, это поможет. Удачи!

2 голосов
/ 02 мая 2019

Как насчет:

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

Также, возможно, подумайте, если это соответствует вашему дизайну:

export interface FooInterface<T> {
  items: T[];
  options: FooOptions<T>;
}
type FooInterfaceString = FooInterface<string>;
1 голос
/ 02 мая 2019

Вы можете использовать псевдоним TypeScript :

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

// Usage
const t: FooInterfaceOfType<string>;
...