【发布时间】:2018-03-19 06:51:04
【问题描述】:
在 Typescript 中,我们已经映射类型,可以将属性从一种类型映射到另一种类型。
一个常见的例子是 Partial 类型,它使泛型类型的所有属性都成为“可选”。
我想实现相反的效果,例如Required,其中所有属性都是“必需的”,而不管它们的可选性如何。
这样的事情可能吗?
(由于了解到我的问题很肤浅,请查看更新!)
更新:
一些上下文...
我正在学习映射类型,并受到文档 here 的启发
type Proxy<T> = {
get(): T;
set(value: T): void;
}
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxify<T>(o: T): Proxify<T> {
// ... wrap proxies ...
}
let proxyProps = proxify(props);
我心想,嗯,“我想知道我们能搞什么坏事?”
所以我写了类似的东西:
type ProxyObservable<T> = Observable<T> & {
[P in keyof T]: ProxyObservable<T[P]>;
};
这很酷,因为你可以给它一个这样的类型:
interface Foo {
myNum: number;
myString: string;
myObject: {
someValue: number;
anotherValue: Date;
};
}
你会得到一个ProxyObservable<Foo> 类型,其中每个属性都是同一类型的 Observable,但也有匹配的子属性导航属性(这也是 Observable)。
const foo: ProxyObservable<Foo> = Proxify<Foo>(...)
foo.myNum.subscribe(...)
foo.myObject.subscribe(...)
foo.myObject.someValue.subscribe(...)
不圣洁,我知道。但是很酷。
当您将属性(例如 myObject)设为可选时,就会出现有趣的问题。然后 Typescript 会中断:
foo.myObject.someValue.subscribe(...)
因为它无法辨别要与 Observable 联合的类型是“未定义”还是我们定义的对象。这就是我的问题所在。
但是...我现在也看到这不是“可选”属性的问题,而是一般的可区分联合类型的问题。
我意识到,给定正确的上下文,Typescript 可能能够推断出foo.myObject 属性的类型。我尝试了一些变体:
foo.myObject!.someValue //<- Nope
foo.myObject ? foo.myObject.someValue : ... //<- Nope
if(foo.myObject) foo.myObject.someValue //<- Nope
在我看来,Typescript 编译器应该能够推断出这一点!
谁能告诉我为什么不呢?
【问题讨论】: