在TypeScript中指定初始赋值后的变量类型

在TypeScript中指定初始赋值后的变量类型,typescript,Typescript,我有一个接口Base,接口A和B扩展,A和B都具有唯一的属性,在另一个接口中不存在。在我的代码中,有些数据将根据类型而变化: interface Base { basicProperty: any, basicProperty2: any } interface A extends Base { aSpecificProperty: any } interface B extends Base { bSpecificProperty: any } function(type

我有一个接口
Base
,接口
A
B
扩展,
A
B
都具有唯一的属性,在另一个接口中不存在。在我的代码中,有些数据将根据类型而变化:

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不抱怨类型不包含正确的属性的情况下实现这一点?或者,是否有一种方法可以将
数据的类型从
a | B
重新分配/指定为
a
B

有很多方法可以实现您想要的。如果您的返回基于
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
      });
  }
  // ...
}
接口基础{
基本属性:任何,
基本属性2:任何
}
接口A扩展了基础{
aSpecificProperty:任何
}
接口B扩展了基础{
BSSpecificProperty:任何
}
功能类型工厂(对象:基本,外部:部分){
返回Object.assign(obj,ext)为T;
}
函数myFn(类型):A | B{
常量数据:基={
基本属性:1,
基本属性2:2
}
开关(类型){
案例“A”:
复印机厂


你考虑过使用这个类型的操作符吗

接口IBase{
名称:字符串;
sayName();
}
类实现IBase{
构造函数(公共名称:字符串){}
sayName(){
console.log(名称);
}
昂利亚()
{ 
log(“我只存在于A中”);
}
}
类实现IBase{
构造函数(公共名称:字符串){}
sayName(){
console.log(名称);
}
onlyB()
{ 
log(“我只存在于B中”);
}
}
函数myFunc(参数:T):任意{
常数数据:T=arg;
如果(数据类型)==A类型){
//数据应为A类
data.sayName();
设aObj:A=任意数据;
aObj.onlyA();
}否则如果(数据类型)==数据类型(B)){
//数据类型应为B
data.sayName();
设bObj:B=任意数据;
bObj.onlyB();
}
返回数据;
}
设a=myFunc(新的a(“我是a”));
设b=myFunc(新b(“我是b”);
a、 onlyA();

b、 onlyB();
我更新了这个问题,使它对我的用例更具体一点。好的,我明白了。让我问你,关于在
if
con块中创建
data
对象,这是你的一个选项吗?否则你需要将
data
声明为你的
Base
接口(
data:Base
)您将需要使用
cast
操作来更改
if
条件中的类型。我在上面的示例中简化了数据,但数据是一个大对象…因此,如果我在每个条件中复制数据,将会有大量重复。实际上,我通过查看您对
cast
的建议,分别想出了该怎么做(我创建没有类型的“基本数据”,然后为A和B创建具有各自类型的变量)并在if块中赋值。这有意义吗?如果是您的场景,它有意义。根据您的更新和注释,我用新的代码段更新了我的答案。