Skip to content

Commit 387f484

Browse files
authored
types: Remove Function type from PropType type (#352)
1 parent e1d300d commit 387f484

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

src/component/componentProps.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ type RequiredKeys<T, MakeDefaultRequired> = {
3030

3131
type OptionalKeys<T, MakeDefaultRequired> = Exclude<keyof T, RequiredKeys<T, MakeDefaultRequired>>;
3232

33+
type ExtractFunctionPropType<
34+
T extends Function,
35+
TArgs extends Array<any> = any[],
36+
TResult = any
37+
> = T extends (...args: TArgs) => TResult ? T : never;
38+
39+
type ExtractCorrectPropType<T> = T extends Function
40+
? ExtractFunctionPropType<T>
41+
: Exclude<T, Function>;
42+
3343
// prettier-ignore
3444
type InferPropType<T> = T extends null
3545
? any // null & true would fail to infer
@@ -38,7 +48,7 @@ type InferPropType<T> = T extends null
3848
: T extends ObjectConstructor | { type: ObjectConstructor }
3949
? { [key: string]: any }
4050
: T extends Prop<infer V, true | false>
41-
? V
51+
? ExtractCorrectPropType<V>
4252
: T;
4353

4454
// prettier-ignore

test/types/defineComponent.spec.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import { createComponent, defineComponent, createElement as h, ref, SetupContext, PropType } from '../../src';
1+
import {
2+
createComponent,
3+
defineComponent,
4+
createElement as h,
5+
ref,
6+
SetupContext,
7+
PropType,
8+
} from '../../src';
29
import Router from 'vue-router';
310

411
const Vue = require('vue/dist/vue.common.js');
512

6-
type Equal<Left, Right> = (<U>() => U extends Left ? 1 : 0) extends (<U>() => U extends Right
7-
? 1
8-
: 0)
13+
type Equal<Left, Right> = (<U>() => U extends Left ? 1 : 0) extends <U>() => U extends Right ? 1 : 0
914
? true
1015
: false;
1116

@@ -105,6 +110,28 @@ describe('defineComponent', () => {
105110
expect.assertions(3);
106111
});
107112

113+
it('custom props type inferred from PropType', () => {
114+
interface User {
115+
name: string;
116+
}
117+
const App = defineComponent({
118+
props: {
119+
user: Object as PropType<User>,
120+
func: Function as PropType<() => boolean>,
121+
userFunc: Function as PropType<(u: User) => User>,
122+
},
123+
setup(props) {
124+
type PropsType = typeof props;
125+
isSubType<{ user?: User }, PropsType>(true);
126+
isSubType<PropsType, { user?: User; func?: () => boolean; userFunc?: (u: User) => User }>(
127+
true
128+
);
129+
},
130+
});
131+
new Vue(App);
132+
expect.assertions(2);
133+
});
134+
108135
it('no props', () => {
109136
const App = defineComponent({
110137
setup(props, ctx) {

0 commit comments

Comments
 (0)