在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块中赋值。这有意义吗?如果是您的场景,它有意义。根据您的更新和注释,我用新的代码段更新了我的答案。