我需要一个RxJS操作符,它可以判断对象上的属性是否存在,然后更改类型以正确反映这一点.
我已经有一个运算符,它将对发出的值执行此操作:
const notUndefined = <T>() =>
filter<T | undefined, T>(
(x): x is T extends undefined ? never : T => x !== undefined
);
但我还需要能够为它的一个属性执行此操作,该属性可以使用以下内容:
interface MyInterface {
myKey?: string;
}
of<MyInterface>({ myKey: "Some value" }).pipe(
notUndefinedKey("myKey"),
map((x) => x.myKey)
// ^? (property) myKey: string
)
of<MyInterface>({ myKey: "Some value" }).pipe(
map((x) => x.myKey)
// ^? (property) MyInterface.myKey?: string | undefined
)
我已经有了第一个可用的版本,但它似乎有点过多,而且似乎还从对象中移除了方法:
import { OperatorFunction, filter, of, map } from "rxjs";
// Typescript types helper
type DefinedFields<TType> = {
[TKey in keyof TType]-?: DefinedFields<NonNullable<TType[TKey]>>;
};
type WithDefinedKey<TType, TKey extends keyof TType> = Omit<TType, TKey> & DefinedFields<Pick<TType, TKey>>;
type OperatorToDefinedKey<TType, TKey extends keyof TType> = OperatorFunction<
TType | undefined,
WithDefinedKey<TType, TKey>
>;
// Operator
export const notUndefinedKey = <TType, TKey extends keyof TType>(
key: TKey
): OperatorToDefinedKey<TType, TKey> =>
filter<TType>((x) => x?.[key] !== undefined) as OperatorToDefinedKey<
TType,
TKey
>;
有什么好办法吗?它可能还保留了更多原始接口,如对象上的方法?