Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Interface 在Typescript中混合接口_Interface_Typescript - Fatal编程技术网

Interface 在Typescript中混合接口

Interface 在Typescript中混合接口,interface,typescript,Interface,Typescript,我有一个包含80多个方法的类,每个方法都接受一个包含一些已定义接口的对象 类内容{ /*更多*/ getAccount(请求:IAccount,回调:ICallback){ 返回此。_调用('getAccount',req,回调); } getid(请求:iid,回调:ICallback){ 返回此命令。_调用('getid',req,callback); } /*更多*/ } 相当“无聊”的东西,因为它只是映射到底层的\u call方法,并使每个方法的类型安全 但有时这些reqparam对象

我有一个包含80多个方法的类,每个方法都接受一个包含一些已定义接口的对象

类内容{
/*更多*/
getAccount(请求:IAccount,回调:ICallback){
返回此。_调用('getAccount',req,回调);
}
getid(请求:iid,回调:ICallback){
返回此命令。_调用('getid',req,callback);
}
/*更多*/
}
相当“无聊”的东西,因为它只是映射到底层的
\u call
方法,并使每个方法的类型安全

但有时这些
req
param对象由2个或更多接口组成,而不是每次出现“尴尬”时都创建另一个接口,如下所示:

interface Abc {
    val foo: Int
}

class HelloAbc : Abc {
    val foo = 5
}

class MyClass : Abc by HelloAbc() {
    val bar = "Hello world"
}
导出接口ILoled扩展IAccount{
loled:布尔型;
}
导出接口IROFOLED扩展ILoled{
rofld:布尔型;
}
课堂材料{
获取LOLS(请求:ILoled){
}
getRofls(要求:IROFOLED){
}
}
有没有办法把它作为方法参数列表中接口的“内联”混入?比如(这显然不起作用):

类内容{
GetMoreTuff(请求:){
}
}
有没有办法把它作为方法参数列表中接口的“内联”混合

不可以。您不能扩展内联接口

是的,您可以。调用交叉口类型,使用
操作符组合类型

function extend<T, U>(first: T, second: U): T & U {
  let result = <T & U> {};
  for (let id in first) {
    result[id] = first[id];
  }

  for (let id in second) {
    if (!result.hasOwnProperty(id)) {
      result[id] = second[id];
    }
  }
  return result;
}

var x = extend({ a: "hello" }, { b: 42 });
x.a; // works
x.b; // works 
函数扩展(第一个:T,第二个:U):T&U{
让结果={};
for(让id先输入){
结果[id]=第一个[id];
}
for(让id以秒为单位){
如果(!result.hasOwnProperty(id)){
结果[id]=第二个[id];
}
}
返回结果;
}
var x=extend({a:hello},{b:42});
x、 a;//作品
x、 b;//作品

我不确定这是否有帮助,但您知道Kotlin通过关键字
进行的接口实现委托吗?
在Kotlin中,您基本上可以创建一个实现一个接口的类,并使用它将同一接口的实现委托给另一个类,如下所示:

interface Abc {
    val foo: Int
}

class HelloAbc : Abc {
    val foo = 5
}

class MyClass : Abc by HelloAbc() {
    val bar = "Hello world"
}
上面的代码创建了一个名为
Abc
的接口,一个实现该接口的类
HelloAbc
,以及另一个类
MyClass
,该类使用
HelloAbc
实现
Abc

我刚刚意识到它在TypeScript中也很有用,我可以提出一个类型安全的mixin实现,如下所示:

type UnionToIntersectionUnchecked<T> =
    (T extends any
        ? (k: T) => void
        : never
        ) extends ((k: infer I) => void)
            ? I
            : never

type IsUnion<T> = [T] extends [UnionToIntersectionUnchecked<T>] ? false : true

type UnionToIntersection<T> =
    IsUnion<T> extends true
        ? UnionToIntersectionUnchecked<T>
        : T

function deepCopy<T, U>(target: T, source: U): T & U {

    const chain = []

    for (let proto = source; source !== Object.prototype; source = Object.getPrototypeOf(source))
        chain.unshift(proto)

    for (const proto of chain)
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(proto))

    return target as T & U
}

function mixin<
    TBase extends object,
    T extends object[]
    >(
        baseClass: { new (...args: any[]): TBase },
        ...objects: T
    ): { new (): TBase & UnionToIntersection<T[number]> } {

    const proto = Object.assign(Object.create(baseClass.prototype), ...objects)

    const ctor = (function(this: TBase, ...args: any[]) {

        const thisProto = Object.getPrototypeOf(this)
        const instance = new baseClass(...args)

        Object.setPrototypeOf(instance, deepCopy(proto, thisProto))

        return instance
    }) as any

    Object.setPrototypeOf(ctor, baseClass)

    return ctor
}
你甚至可以在电脑上测试它


您可能希望在性能关键的代码中避免这种情况,因为创建所有这些原型的成本可能会很高,但我不认为它会对总体产生太大的影响。

恐怕您必须声明一个超级接口。