Skip to content

Commit 7f7bb80

Browse files
committed
feat: add 0213-hard-vue-basice-props
1 parent c8d7095 commit 7f7bb80

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// 参考 https://github.com/type-challenges/type-challenges/issues/6557
2+
// 好难...
3+
type ClassToType<C> = C extends () => infer T // String/Number/Boolean
4+
? T
5+
: C extends unknown[]
6+
? ClassToType<C[number]>
7+
: C extends new (...args: any) => unknown // user defined constructors
8+
? InstanceType<C>
9+
: never;
10+
11+
// computed props
12+
type ComputedPropsType<P> = {
13+
[key in keyof P]: P[key] extends { type: infer T }
14+
? ClassToType<T>
15+
: {} extends P[key]
16+
? any
17+
: ClassToType<P[key]>;
18+
};
19+
20+
// computed value
21+
type ComputedValuesType<C> = {
22+
[K in keyof C]: C[K] extends (...args: unknown[]) => infer R ? R : never;
23+
};
24+
25+
declare function VueBasicProps<P, D, C, M>(options: {
26+
props: P;
27+
data: (this: ComputedPropsType<P>) => D;
28+
computed: C & ThisType<D & ComputedPropsType<P>>;
29+
methods: M & ThisType<D & ComputedValuesType<C> & M & ComputedPropsType<P>>;
30+
}): any;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type { Debug, Equal, Expect, IsAny } from "@type-challenges/utils";
2+
3+
class ClassA {}
4+
5+
VueBasicProps({
6+
props: {
7+
propA: {},
8+
propB: { type: String },
9+
propC: { type: Boolean },
10+
propD: { type: ClassA },
11+
propE: { type: [String, Number] },
12+
propF: RegExp,
13+
},
14+
data(this) {
15+
type PropsType = Debug<typeof this>;
16+
type cases = [
17+
Expect<IsAny<PropsType["propA"]>>,
18+
Expect<Equal<PropsType["propB"], string>>,
19+
Expect<Equal<PropsType["propC"], boolean>>,
20+
Expect<Equal<PropsType["propD"], ClassA>>,
21+
Expect<Equal<PropsType["propE"], string | number>>,
22+
Expect<Equal<PropsType["propF"], RegExp>>
23+
];
24+
25+
// @ts-expect-error
26+
this.firstname;
27+
// @ts-expect-error
28+
this.getRandom();
29+
// @ts-expect-error
30+
this.data();
31+
32+
return {
33+
firstname: "Type",
34+
lastname: "Challenges",
35+
amount: 10,
36+
};
37+
},
38+
computed: {
39+
fullname() {
40+
return `${this.firstname} ${this.lastname}`;
41+
},
42+
},
43+
methods: {
44+
getRandom() {
45+
return Math.random();
46+
},
47+
hi() {
48+
alert(this.fullname.toLowerCase());
49+
alert(this.getRandom());
50+
},
51+
test() {
52+
const fullname = this.fullname;
53+
const propE = this.propE;
54+
type cases = [
55+
Expect<Equal<typeof fullname, string>>,
56+
Expect<Equal<typeof propE, string | number>>
57+
];
58+
},
59+
},
60+
});

0 commit comments

Comments
 (0)