在 Typescript 中,我们有映射类型,可以将属性从一种类型映射到另一种类型。
一个常见的示例是 Partial 类型,它使泛型类型上的所有属性都成为“可选”。
我想实现相反的效果,比如“必需”,其中所有属性都被设置为“必需”,而不管它们预先的可选性如何。
这样的事可能吗?
(既然知道我的问题很肤浅,请参阅更新!)
Update:
一些背景...
我正在学习映射类型,并受到文档的启发here https://www.typescriptlang.org/docs/handbook/advanced-types.html
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>
type,其中每个属性都是相同类型的 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 编译器应该能够推断出这一点!
谁能告诉我为什么不呢?