Typescript 将工厂创建的对象推送到数组时更正类型声明
在typescript中,如果我有一个工厂方法,它可能根据运行时值生成不同的对象。如何声明所创建对象的结果数组是一种类型还是另一种类型,而不是两种类型Typescript 将工厂创建的对象推送到数组时更正类型声明,typescript,Typescript,在typescript中,如果我有一个工厂方法,它可能根据运行时值生成不同的对象。如何声明所创建对象的结果数组是一种类型还是另一种类型,而不是两种类型 interface Foo { fooProp: 'Foo' } interface Bar { barProp: 'Bar' } function barFactory(): Bar { return { barProp: 'Bar' } } function fooFactory(): Foo { ret
interface Foo {
fooProp: 'Foo'
}
interface Bar {
barProp: 'Bar'
}
function barFactory(): Bar {
return { barProp: 'Bar' }
}
function fooFactory(): Foo {
return { fooProp: 'Foo' }
}
let factory: (() => Foo) | (() => Bar);
let someRuntimeValue = true;
if (someRuntimeValue) {
factory = fooFactory;
} else {
factory = barFactory;
}
let objects: Foo[] | Bar[];
for (let n = 0; n < 10; ++n) {
//TS - Argument of type 'Foo | Bar' is not assignable
//to parameter of type 'Foo & Bar'.
objects.push(factory());
}
接口Foo{
fooProp:‘Foo’
}
接口条{
酒吧道具:“酒吧”
}
函数barFactory():Bar{
返回{barProp:'Bar'}
}
函数fooFactory():Foo{
返回{fooProp:'Foo'}
}
让工厂:(()=>Foo)|(()=>Bar);
让someRuntimeValue=true;
if(someRuntimeValue){
工厂=食品工厂;
}否则{
工厂=酒吧工厂;
}
让对象:Foo[]| Bar[];
对于(设n=0;n<10;++n){
//TS-类型为“Foo | Bar”的参数不可赋值
//到类型为“Foo&Bar”的参数。
push(factory());
}
如果它不是一个运行时值,您可能会使用模板(只要您的代码被封装在函数、类或接口中),但由于它是一个变量,您必须使用作为任何
短语,使编译器在代码中“忽略它”,如下所示:
let对象:Foo[]| Bar[];
对于(设n=0;n<10;++n){
objects.push(factory()如有);//忽略'Foo | Bar'返回类型
}
在typescript中,尤其是在执行类似操作时,您必须将用作任何短语——只需确保操作正确,因为编译器将跳过此处的类型检查
例如,以后可能希望将其传递给只处理Foo[]
类型的函数;您必须使用类似的工具:
函数testFoo(对象:Foo[]){
return!objects.find(a=>!(a.fooProp));
}
if(someRuntimeValue){
testFoo(对象为Foo[]);
}
如果它不是一个运行时值,您可能会使用模板(只要您的代码被封装在函数、类或接口中),但由于它是一个变量,您必须使用作为任何
短语,使编译器在代码中“忽略它”,如下所示:
let对象:Foo[]| Bar[];
对于(设n=0;n<10;++n){
objects.push(factory()如有);//忽略'Foo | Bar'返回类型
}
在typescript中,尤其是在执行类似操作时,您必须将用作任何短语——只需确保操作正确,因为编译器将跳过此处的类型检查
例如,以后可能希望将其传递给只处理Foo[]
类型的函数;您必须使用类似的工具:
函数testFoo(对象:Foo[]){
return!objects.find(a=>!(a.fooProp));
}
if(someRuntimeValue){
testFoo(对象为Foo[]);
}
Array
?我想要一个或另一个,尽管Foo[]| Bar[]
不是[Bar,Foo,Foo,Bar,…]
好吧,我不确定,让我们看看是否有人提出建议。Array
我想要一个或另一个,尽管Foo[]| Bar[/code>不是[Bar,Foo,Foo,Bar,
好吧,我不确定,让我们看看是否有人提出了建议。您的代码没有什么意义:每个对象
项都有一个Foo&Bar
类型(OPs代码中没有一个类型满足它)。实际上,在这里使用作为any
并不能更好地将对象声明为any
,而完全不使用任何类型。恐怕你错了:如果要遵循工厂()
返回类型,则对象的每个项都有Foo | Bar
类型。在这段代码中,对象
仍然保留其类型定义,而我们仅在特定情况下绕过它。因为它保留了它的类型定义(不管它有多僵硬),我们可以在以后保留某种形式的类型检查,并按照第二个示例所示进行操作。您自己检查一下如何“仍然保留它的类型定义”——正如我指出的,如果您单击上面的链接,您将看到一个无意义的不存在的交叉点类型。如果您将其声明为Array
正确,那么它将具有Foo | Bar
类型——类型定义确实非常不灵活——但它并非毫无意义。我们知道类型不是一个就是另一个——因此,每次OP想要处理对象变量时,他们必须确定类型(使用someRuntimeVariable
)并将转换为关键字,或者将其视为不灵活的交集类型;我相信这就是他们想要的。你的代码没有什么意义:每一个对象
都有一个Foo&Bar
类型(并且OPs代码中没有一个类型满足它)。实际上,在这里使用作为any
并不能更好地将对象声明为any
,而完全不使用任何类型。恐怕你错了:如果要遵循工厂()
返回类型,则对象的每个项都有Foo | Bar
类型。在这段代码中,对象
仍然保留其类型定义,而我们仅在特定情况下绕过它。因为它保留了它的类型定义(不管它有多僵硬),我们可以在以后保留某种形式的类型检查,并按照第二个示例所示进行操作。您自己检查一下如何“仍然保留它的类型定义”——正如我指出的,如果您单击上面的链接,您将看到一个无意义的不存在的交叉点类型。如果您将其声明为Array
正确,那么它将具有Foo | Bar
类型——类型定义确实非常不灵活——但它并非毫无意义。我们知道类型不是一个就是另一个——因此,每次OP想要处理对象变量时,他们必须确定类型(使用someRuntimeVariable
)并将转换为关键字,或者将其视为不灵活的交集类型;