打字稿区分联合类型 Observable.of
Typescript discriminated union types with Observable.of
我正在尝试将 Typescript 2.0 的可区分联合类型与 RxJS 一起使用,但我收到一个错误,指出我正在 returning 的对象不是联合类型之一类型。
这是我的类型:
interface Square {
kind: "square";
width: number;
}
interface Circle {
kind: "circle";
radius: number;
}
interface Center {
kind: "center";
}
type Shape = Square | Circle | Center;
我只是 return 一个 Shape
而不使用 Observable
的这个函数完全可以编译:
function shapeFactory(width: number): Shape {
if (width > 5) {
return {kind: "circle", radius: width};
} else if (width < 2) {
return {kind: "square", width: 3};
}
return {kind: "center"};
}
当我改为尝试 return 一个 Observable<Shape>
时:
function shapeFactoryAsync(width: number): Observable<Shape> {
if (width > 5) {
return Observable.of({kind: "circle", radius: width});
} else {
return Observable.of({kind: "center"});
}
}
我遇到编译错误:
Type 'Observable<{ kind: string; radius: number; }>' is not assignable to type 'Observable<Shape>'.
Type '{ kind: string; radius: number; }' is not assignable to type 'Shape'.
Type '{ kind: string; radius: number; }' is not assignable to type 'Center'.
Types of property 'kind' are incompatible.
Type 'string' is not assignable to type '"center"'.
我希望我的第一个 return 类型是 Observable<{ kind: "circle"; radius: number; }>
,因为 kind
是所有 Shape
类型的区别。奇怪的是,Observable.of({kind: "center"})
没问题,可能是因为没有其他数据与之关联?
如果我显式分配对象并给分配一个类型,我就能修复它:
let circle: Circle = {kind: "circle", radius: width};
return Observable.of(circle);
虽然这看起来应该是一个不必要的转换。
我这样做是完全错误的,还是为了弄清楚 kind
的值应该是 "circle"
而不是类型 string
是否需要强制转换?
对于像 Observable.of({ kind: "center" })
这样的调用,TypeScript 无法从匿名参数中推断出类型。
您可以通过在调用通用 of
方法时将 type variable 指定为 Shape
来解决您的问题:
function shapeFactoryAsync(width: number): Observable<Shape> {
if (width > 5) {
return Observable.of<Shape>({ kind: "circle", radius: width });
} else {
return Observable.of<Shape>({ kind: "center" });
}
}
指定类型变量后,TypeScript 不再需要推断类型。
我正在尝试将 Typescript 2.0 的可区分联合类型与 RxJS 一起使用,但我收到一个错误,指出我正在 returning 的对象不是联合类型之一类型。
这是我的类型:
interface Square {
kind: "square";
width: number;
}
interface Circle {
kind: "circle";
radius: number;
}
interface Center {
kind: "center";
}
type Shape = Square | Circle | Center;
我只是 return 一个 Shape
而不使用 Observable
的这个函数完全可以编译:
function shapeFactory(width: number): Shape {
if (width > 5) {
return {kind: "circle", radius: width};
} else if (width < 2) {
return {kind: "square", width: 3};
}
return {kind: "center"};
}
当我改为尝试 return 一个 Observable<Shape>
时:
function shapeFactoryAsync(width: number): Observable<Shape> {
if (width > 5) {
return Observable.of({kind: "circle", radius: width});
} else {
return Observable.of({kind: "center"});
}
}
我遇到编译错误:
Type 'Observable<{ kind: string; radius: number; }>' is not assignable to type 'Observable<Shape>'.
Type '{ kind: string; radius: number; }' is not assignable to type 'Shape'.
Type '{ kind: string; radius: number; }' is not assignable to type 'Center'.
Types of property 'kind' are incompatible.
Type 'string' is not assignable to type '"center"'.
我希望我的第一个 return 类型是 Observable<{ kind: "circle"; radius: number; }>
,因为 kind
是所有 Shape
类型的区别。奇怪的是,Observable.of({kind: "center"})
没问题,可能是因为没有其他数据与之关联?
如果我显式分配对象并给分配一个类型,我就能修复它:
let circle: Circle = {kind: "circle", radius: width};
return Observable.of(circle);
虽然这看起来应该是一个不必要的转换。
我这样做是完全错误的,还是为了弄清楚 kind
的值应该是 "circle"
而不是类型 string
是否需要强制转换?
对于像 Observable.of({ kind: "center" })
这样的调用,TypeScript 无法从匿名参数中推断出类型。
您可以通过在调用通用 of
方法时将 type variable 指定为 Shape
来解决您的问题:
function shapeFactoryAsync(width: number): Observable<Shape> {
if (width > 5) {
return Observable.of<Shape>({ kind: "circle", radius: width });
} else {
return Observable.of<Shape>({ kind: "center" });
}
}
指定类型变量后,TypeScript 不再需要推断类型。