Typescript 不允许使用keyof的参数(“应为0个参数,但得到1”)
尝试以递归/嵌套方式实现一种类型,其中基本属性的类型为Typescript 不允许使用keyof的参数(“应为0个参数,但得到1”),typescript,Typescript,尝试以递归/嵌套方式实现一种类型,其中基本属性的类型为KnockoutObservable: export type Primitive = string | number | boolean | undefined | null; export type KnockoutMappedProperty<T> = T extends Primitive ? KnockoutObservable<T> : KnockoutMappedType<T>; exp
KnockoutObservable
:
export type Primitive = string | number | boolean | undefined | null;
export type KnockoutMappedProperty<T> = T extends Primitive ? KnockoutObservable<T> : KnockoutMappedType<T>;
export type KnockoutMappedType<T> = {
[Property in keyof T]: KnockoutMappedProperty<T[Property]>;
};
interface KnockoutObservable<T> extends KnockoutSubscribable<T>, KnockoutObservableFunctions<T> {
(): T;
(value: T): void;
/*...*/
}
Intellisense告诉我,v1.prop
属于KnockoutObservable | KnockoutObservable
类型。为什么某些东西被拆分成一个应该是可观察的联合类型
以下代码再次编译为罚款:
const prop: KnockoutObservable<boolean> = v1.prop;
prop(true);
const-prop:KnockoutObservable=v1.prop;
道具(真实);
为什么我需要引入类型为KnockoutObservable
的变量
问题在于,条件类型分布在联合上,如中所述。虽然一开始可能并不明显,
boolean
是一个并集,但该并集true | false
。这意味着映射的prop1
类型将为KnockoutObservable | KnockoutObservable
。这意味着唯一可调用的签名将是公共签名,即没有任何参数的签名
要停止分发行为,可以将类型参数封装在元组中(因为分发只发生在裸类型参数上)
export type Primitive=string | number | boolean | undefined | null;
导出类型KnockoutMappedProperty=[T]扩展[Primitive]?KnockoutObservable:KnockoutMappedType;
导出类型KnockoutMappedType={
[keyof T中的属性]:KnockoutMappedProperty;
};
接口KnockoutObservable扩展了KnockoutSubscribable、KnockoutObserveFunctions{
():T;
(值:T):无效;
/*...*/
}
const v1:KnockoutMappedType=null;
常量propValue:boolean=v1.prop();
v1.道具(正确);//好啊
v1.prop(true); // Gives compiler error: Expected 0 arguments, but got 1
const prop: KnockoutObservable<boolean> = v1.prop;
prop(true);
export type Primitive = string | number | boolean | undefined | null;
export type KnockoutMappedProperty<T> = [T] extends [Primitive] ? KnockoutObservable<T> : KnockoutMappedType<T>;
export type KnockoutMappedType<T> = {
[Property in keyof T]: KnockoutMappedProperty<T[Property]>;
};
interface KnockoutObservable<T> extends KnockoutSubscribable<T>, KnockoutObservableFunctions<T> {
(): T;
(value: T): void;
/*...*/
}
const v1: KnockoutMappedType<{ prop: boolean }> = null;
const propValue: boolean = v1.prop();
v1.prop(true); // ok