在TypeScript

时间:2017-04-13 22:00:35

标签: typescript

我有一个接口Base,接口AB扩展,AB都具有唯一且不具有的属性存在于另一个。在我的代码中,我有一些数据会根据类型而改变:

interface Base {
  basicProperty: any,
  basicProperty2: any
}

interface A extends Base {
  aSpecificProperty: any
}

interface B extends Base {
  bSpecificProperty: any
}

function(type): A | B {
  const data: A | B = {
    basicProperty: 1,
    basicProperty2: 2
  }

  if (type === 'A') {
    // Data should be type A
    data.aSpecificProperty = 3;
  } else if (type === 'B') {
    // Data should be type B
    data.bSpecificProperty = 3;
  }

  return data;
}

如果没有TypeScript抱怨不包含正确属性的类型,有没有办法实现这个目的?或者,有没有办法从dataA | BA重新分配/指定B的类型?

2 个答案:

答案 0 :(得分:0)

有很多方法可以达到你想要的效果。如果您的返回基于type: string参数,为什么不使用以下内容:

interface Base { }
class A implements Base { name: string }
class B implements Base { value: number }

function fn(type): Base {
  if (type == 'A') {
    const data: A = {
      name: 'abc'
    }
    //...
    return data;
  }

  if (type == 'B') {
    const data: B = {
      value: 10
    }
    //...
    return data;
  }
}

我需要更多关于你的问题的信息才能给出更好的答案,但是,因为你所说的Base课程,这样的课程可以帮助你。

<强>更新

根据您的更新和评论,我建议使用以下代码:

interface Base {
  basicProperty: any,
  basicProperty2: any
}

interface A extends Base {
  aSpecificProperty: any
}

interface B extends Base {
  bSpecificProperty: any
}

function typeFactory<T extends Base>(obj: Base, ext: Partial<T>) {
  return Object.assign(obj, ext) as T;
}

function myFn(type): A | B {
  const data: Base = {
    basicProperty: 1,
    basicProperty2: 2
  }

  switch (type) {
    case 'A':
      return typeFactory<A>(data, {
        aSpecificProperty: 3
      });
    case 'B':
      return typeFactory<B>(data, {
        bSpecificProperty: 3
      });
  }
  // ...
}
  

有关Object.assign(...) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

的参考资料

答案 1 :(得分:0)

您是否考虑过使用typeof运算符?

&#13;
&#13;
interface IBase {
    name: string;
    sayName();
    }


class A implements IBase {
    constructor(public name: string) {  }
    sayName() {
        console.log(name);
    }

    onlyA()
    { 
        console.log("I exist only in A");
    }
}

class B implements IBase {
    constructor(public name: string) {  }
    sayName() {
        console.log(name);
    }

    onlyB()
    { 
        console.log("I exist only in B");
    }
}

function myFunc<T extends IBase>(arg: T ) : any {
    
    const data: T = arg;

    if (typeof(data) === typeof(A)) {
        // Data should be type A
        data.sayName();
        let aObj: A = data as any;
        aObj.onlyA();
    } else if (typeof(data) === typeof(B)) {
        // Data should be type B
        data.sayName();
        let bObj: B = data as any;
        bObj.onlyB();
    }

    return data;
}

let a = myFunc(new A("I am A"));
let b = myFunc(new B("I am B"));

a.onlyA();
b.onlyB();
&#13;
&#13;
&#13;

这实际上让泛型函数检查类型并返回任何类型的对象。

这是你在寻找什么,或者我没有正确地回答这个问题?

根据您的示例,它看起来像

&#13;
&#13;
interface IBase{

}

class A implements IBase { 

}

class B implements IBase{

}

function myFunc<T extends IBase>(type: T ): A | B {
    const data: A | B = {

    }

    if (typeof(type) === typeof(A)) {
        // Data should be type A
    } else if (typeof(type) === typeof(B)) {
        // Data should be type B
    }

    return data;
}
&#13;
&#13;
&#13;