forked from anuraghazra/type-trident
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
92 lines (80 loc) · 2.02 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
type TrimWhiteSpace<Str extends string> = string extends Str
? "Error"
: Str extends ` ${infer Str}` | `\n${infer Str}`
? TrimWhiteSpace<Str>
: Str;
type GetType<Str extends string> = string extends Str
? "Error"
: Str extends `${infer Value}px`
? number
: string;
// "font-size" -> "fontSize"
// "grid-column-start" -> "gridColumnStart"
type KebabCaseToCamelCase<Str extends string> = string extends Str
? "Error"
: Str extends `${infer Part1}-${infer Part2}`
? `${Part1}${Capitalize<KebabCaseToCamelCase<Part2>>}`
: Str;
type ParseCSSProps<S extends string> =
S extends `${infer Prop}:${infer Value};${infer Rest}`
? {
[k in KebabCaseToCamelCase<TrimWhiteSpace<Prop>>]: GetType<
TrimWhiteSpace<Value>
>;
} & ParseCSSProps<Rest>
: unknown;
type GetRestCSS<Rest extends string> =
TrimWhiteSpace<Rest> extends `${infer Content}}${infer RRest}` ? RRest : Rest;
type ParseRestCSS<Rest extends string> =
TrimWhiteSpace<Rest> extends `${infer Content}}${infer RRest}`
? ParseCSSProps<Content>
: string;
type ParseCSS<S extends string> = string extends S
? "Error"
: TrimWhiteSpace<S> extends `${infer ClassName} {${infer Rest}`
?
| {
[k in TrimWhiteSpace<ClassName>]: ParseRestCSS<Rest>;
}
| ParseCSS<GetRestCSS<Rest>>
: string;
type CSSTypes = ParseCSS<`
body {
max-width: 20px;
background-color: lightblue;
animation-timing-function: ease;
}
.h1 {
color: white;
}
#p {
font-family: verdana;
font-size: 20px;
}
`>;
const allRight: CSSTypes = {
body: {
backgroundColor: "red",
maxWidth: 100,
animationTimingFunction: "ease",
},
"#p": {
fontFamily: "verdana",
fontSize: 10,
},
".h1": { color: "white" },
};
// @ts-expect-error
const willError: CSSTypes = {
// Property '"max-width"' is missing in
body: {
backgroundColor: "red",
animationTimingFunction: "ease",
},
"#p": {
fontFamily: "verdana",
fontSize: 10,
},
".h1": { color: "white" },
};
export {};