简体   繁体   English

如何基于通用打字稿界面创建特定别名

[英]How to create a specific alias based on a generic typescript interface

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: 现在,每当我需要对此做些事情时,我都需要重复T。例如:

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: 现在,重复很无聊,是否有可能创建一个类型或接口,其中T对于这两种类型都应该是字符串,或者以某种方式重新定义接口,所以我改为这样写:

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

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>;

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 : 这里的其他答案是正确的,但是我想补充一点,如果您通常(但不总是)仅将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;
}

That lets you just leave out the O parameter when you intend it to just be FooOptions<T> : 这样,当您打算将其作为FooOptions<T>时,就FooOptions<T> O参数:

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: 并且,如果您实际上希望OFooOptions<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"); }
    }
}

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>> : 哦,如果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);
        }
    }
}

Okay, hope that helps. 好的,希望对您有所帮助。 Good luck! 祝好运!

You could use a TypeScript alias : 您可以使用TypeScript别名

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

// Usage
const t: FooInterfaceOfType<string>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM