Skip to content

Commit

Permalink
types: Remove Function type from PropType type (#352)
Browse files Browse the repository at this point in the history
  • Loading branch information
pikax authored Jun 7, 2020
1 parent e1d300d commit 387f484
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
12 changes: 11 additions & 1 deletion src/component/componentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ type RequiredKeys<T, MakeDefaultRequired> = {

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

type ExtractFunctionPropType<
T extends Function,
TArgs extends Array<any> = any[],
TResult = any
> = T extends (...args: TArgs) => TResult ? T : never;

type ExtractCorrectPropType<T> = T extends Function
? ExtractFunctionPropType<T>
: Exclude<T, Function>;

// prettier-ignore
type InferPropType<T> = T extends null
? any // null & true would fail to infer
Expand All @@ -38,7 +48,7 @@ type InferPropType<T> = T extends null
: T extends ObjectConstructor | { type: ObjectConstructor }
? { [key: string]: any }
: T extends Prop<infer V, true | false>
? V
? ExtractCorrectPropType<V>
: T;

// prettier-ignore
Expand Down
35 changes: 31 additions & 4 deletions test/types/defineComponent.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { createComponent, defineComponent, createElement as h, ref, SetupContext, PropType } from '../../src';
import {
createComponent,
defineComponent,
createElement as h,
ref,
SetupContext,
PropType,
} from '../../src';
import Router from 'vue-router';

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

type Equal<Left, Right> = (<U>() => U extends Left ? 1 : 0) extends (<U>() => U extends Right
? 1
: 0)
type Equal<Left, Right> = (<U>() => U extends Left ? 1 : 0) extends <U>() => U extends Right ? 1 : 0
? true
: false;

Expand Down Expand Up @@ -105,6 +110,28 @@ describe('defineComponent', () => {
expect.assertions(3);
});

it('custom props type inferred from PropType', () => {
interface User {
name: string;
}
const App = defineComponent({
props: {
user: Object as PropType<User>,
func: Function as PropType<() => boolean>,
userFunc: Function as PropType<(u: User) => User>,
},
setup(props) {
type PropsType = typeof props;
isSubType<{ user?: User }, PropsType>(true);
isSubType<PropsType, { user?: User; func?: () => boolean; userFunc?: (u: User) => User }>(
true
);
},
});
new Vue(App);
expect.assertions(2);
});

it('no props', () => {
const App = defineComponent({
setup(props, ctx) {
Expand Down

0 comments on commit 387f484

Please sign in to comment.