【发布时间】:2021-09-09 21:59:37
【问题描述】:
我有一个将对象作为参数的defineComponent() 函数。该对象可以包含一个props 属性和一个接收props 参数的setup() 属性,该参数的类型是从该对象之前声明的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;
【问题讨论】:
-
我认为可能是这种情况github.com/microsoft/TypeScript/issues/43948 但他是我的第一个猜测,因为示例非常复杂
-
你想达到什么目的?我相信
validator方法应该根据type属性推断参数类型。我认为对validator参数使用显式类型是错误的。validator参数被推断为unknown的事实可能是一个错误。这只是我的看法 -
@captain-yossarian 感谢您提供问题链接。这可能是这里的问题。
-
@captain-yossarian 目标是从先前声明的
props属性中推断出setup()中的props参数。我同意打字中可能存在一些错误,我有兴趣修复它。