typescript - 为什么常规函数会破坏类型推断?
问题描述
我有一个defineComponent()
将对象作为参数的函数。该对象可以包含一个props
属性和一个setup()
接收参数的属性,该参数的类型是从对象中先前声明的属性props
推断出来的。props
例子:
defineComponent({
props: {
size: {
type: String,
default: 'lg',
validator: (value: string) => true,
}
},
setup(props) {
console.log(props.size.charAt(0))
}
})
奇怪的是,如果props.size.validator
声明为常规函数 ( validator: function(value: string) { return true }
) 而不是箭头函数,则props
参数的推断类型是完全错误的。对于上面的例子。它应该是:
{
size: string
}
但它是这样的:
string[] | {
[x: string]: Prop<unknown, unknown> | null;
}
常规函数本质上与工作代码中的箭头函数相同,所以我没想到它会破坏类型推断。
为什么常规函数会破坏setup()
'props
参数的类型推断?
mylib.d.ts:
declare interface PropOptions<T = any, D = T> {
type?: PropType<T>;
required?: boolean;
default?: D | DefaultFactory<D>;
validator?(value: unknown): boolean;
}
declare type DefaultFactory<T> = (props: Data) => T;
declare type Data = Record<string, unknown>;
export declare type PropType<T> = PropConstructor<T> | PropConstructor<T>[];
declare type PropConstructor<T = any> = { new (...args: any[]): T & {} };
export declare type Prop<T, D = T> = PropOptions<T, D> | PropType<T>;
export declare type ComponentPropsOptions<P = Data> = ComponentObjectPropsOptions<P> | string[];
export declare type ComponentObjectPropsOptions<P = Data> = { [K in keyof P]: Prop<P[K]> | null };
declare type InferPropType<T> =
[T] extends [null] ? any
: [T] extends [{ type: null | true }] ? any
: [T] extends [ObjectConstructor | { type: ObjectConstructor }] ? Record<string, any>
: [T] extends [BooleanConstructor | { type: BooleanConstructor }] ? boolean
: [T] extends [DateConstructor | { type: DateConstructor }] ? Date
: [T] extends [Prop<infer V, infer D>] ? (unknown extends V ? D : V)
: T;
export declare type ExtractPropTypes<O> =
O extends object
? { [K in keyof O]: InferPropType<O[K]> }
: { [K in string]: any };
export declare interface ComponentOptionsBase<Props> {
setup?: (this: void, props: Props) => any;
}
export declare type ComponentOptionsWithObjectProps<PropsOptions = ComponentObjectPropsOptions, Props = ExtractPropTypes<PropsOptions>>
= ComponentOptionsBase<Props> & { props: PropsOptions };
export declare function defineComponent<PropsOptions extends ComponentPropsOptions>(options: ComponentOptionsWithObjectProps<PropsOptions>): any;
解决方案
更新
type Constructors =
| BooleanConstructor
| ObjectConstructor
| StringConstructor
type DefaultFactory<T> = (props: Data) => T;
type Data = Record<string, unknown>;
type Entity<T extends Constructors> = {
type: T,
default: InstanceType<T> | DefaultFactory<T>
validator: (value: ConstructorMappings<T>) => boolean
}
type ConstructorMappings<T extends Constructors> =
T extends StringConstructor
? string
: T extends BooleanConstructor
? boolean
: T extends ObjectConstructor
? object
: never;
type MakeSetup<Props extends Record<string, Entity<Constructors>>>={
[Prop in keyof Props]:ConstructorMappings<Props[Prop]['type']>
}
interface Props<T extends Constructors> {
props: {
size: Entity<T>
},
setup: (arg: MakeSetup<this['props']>) => any
}
export declare function defineComponent<C extends Constructors>(options: Props<C>): any;
defineComponent({
props: {
size: {
type: String,
default: 'lg',
validator: (value /** infered as a string */) => true,
}
},
setup:(props)=> {
console.log(props.size.charAt(0)) // ok
}
})
如您所见,value
现在可以推断出论证。
推荐阅读
- windows - 从任务计划程序运行时 MSI 安装程序不工作
- python - 如何从标签中获取 src="PATH" 中的路径
- python - for in 循环相同,但结果不同
- assembly - 如何在程序集中更新字符串的字符?
- javascript - react-map-gl - 印度地理位置显示不正确
- angular - ngFor 不显示推送到源数组的新数据的问题
- google-chrome - 如何启动 Chrome 进程并等待它终止
- python - 文本框类在给它一个类时改变大小/位置
- selenium - Chromedriver - “无法确定来自标签崩溃的加载状态”
- angular - 在 Angular HttpClient 中返回 observable 之前等待