Passed
Push — main ( c3163a...9d001c )
by Andrii
03:28
created

__sandbox__/ts.test.ts   A

Complexity

Total Complexity 21
Complexity/F 1.5

Size

Lines of Code 297
Function Count 14

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 21
eloc 224
mnd 7
bc 7
fnc 14
dl 0
loc 297
rs 10
bpm 0.5
cpm 1.5
noi 0
c 0
b 0
f 0

6 Functions

Rating   Name   Duplication   Size   Complexity  
A ts.test.ts ➔ _thising 0 4 2
A ts.test.ts ➔ checkC 0 1 1
A ts.test.ts ➔ check1 0 2 1
A ts.test.ts ➔ checkR 0 1 1
A ts.test.ts ➔ thising 0 5 1
A ts.test.ts ➔ joiner 0 1 3
1
import type { Falsy } from "../src/ts-swiss.types"
2
import type { Action, ClassHash, CssModule } from "../src/definitions.types"
3
4
const {keys: $keys} = Object
5
6
it("`in string` vs `:string`", () => {
7
  type In = {[k in string]: boolean}
8
  type Colon = {[k: string]: boolean}
9
10
  function check1(_: {some: boolean}) {}
11
  function checkR<K extends string>(_: {[k in K]: boolean}) {}
12
  function checkC(_: {[k: string]: boolean}) {}
13
14
  const input1: In = {}, input2: Colon = {}
15
  //@ts-expect-error
16
  check1(input1)
17
  //@ts-expect-error
18
  check1(input2)
19
  checkR(input1)
20
  checkR(input2)
21
  checkC(input1)
22
  checkC(input2)
23
24
})
25
26
describe("this", () => {
27
  type Context = {context: string}
28
29
  it.todo("`this?` is illegal")
30
31
  it("|void - NOPE", () => {
32
    function thising(this: void | Context): typeof this extends Context ? true : null {
33
      //@ts-expect-error
34
      return this && 'context' in this
35
      ? true
36
      : null
37
    }
38
39
    const suite1 = thising()
40
    , suite2 = thising.bind({context: ""})()
41
    , suite1Check: Record<string, typeof suite1> = {
42
      "null": null,
43
      //@ts-expect-error
44
      "true": true
45
    }
46
    , suite2Check: Record<string, typeof suite2> = {
47
      //TODO #13 @ts-expect-error
48
      "null": null,
49
      //@ts-expect-error //TODO #13
50
      "true": true
51
    }
52
53
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
54
  })
55
56
  it("|undefined - NOPE", () => {
57
    function thising(this: undefined | Context): typeof this extends Context ? true : null {
58
      //@ts-expect-error
59
      return this && 'context' in this
60
      ? true
61
      : null
62
    }
63
64
    //@ts-expect-error //TODO #13 The 'this' context of type 'void' is not assignable
65
    const suite1 = thising()
66
    , suite2 = thising.bind({context: ""})()
67
    , suite1Check: Record<string, typeof suite1> = {
68
      "null": null,
69
      //@ts-expect-error
70
      "true": true
71
    }
72
    , suite2Check: Record<string, typeof suite2> = {
73
      //TODO #13 @ts-expect-error
74
      "null": null,
75
      //@ts-expect-error //TODO #13
76
      "true": true
77
    }
78
79
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
80
  })
81
82
  it("|unknown - NOPE", () => {
83
    function thising(this: unknown | Context): typeof this extends Context ? true : null {
84
      //@ts-expect-error
85
      return this && 'context' in this
86
      ? true
87
      : null
88
    }
89
90
    const suite1 = thising()
91
    , suite2 = thising.bind({context: ""})()
92
    , suite1Check: Record<string, typeof suite1> = {
93
      "null": null,
94
      //@ts-expect-error
95
      "true": true
96
    }
97
    , suite2Check: Record<string, typeof suite2> = {
98
      //TODO #13 @ts-expect-error
99
      "null": null,
100
      //@ts-expect-error //TODO #13
101
      "true": true
102
    }
103
104
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
105
  })
106
107
  it("overload", () => {
108
    function thising(): null
109
    function thising(this: Context): true
110
    function thising(this: void | Context) {
111
      return this && 'context' in this
112
      ? true
113
      : null
114
    }
115
116
    const suite1 = thising()
117
    , suite2 = thising.bind({context: ""})()
118
    , suite1Check: Record<string, typeof suite1> = {
119
      "null": null,
120
      //@ts-expect-error
121
      "true": true
122
    }
123
    , suite2Check: Record<string, typeof suite2> = {
124
      //@ts-expect-error
125
      "null": null,
126
      "true": true
127
    }
128
129
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
130
  })
131
132
  it("throw variable - Nope", () => {
133
    function _thising(this: void | Context) {
134
      return this && 'context' in this
135
      ? true
136
      : null
137
    }
138
139
    //Same for ((this: Context) => true) | () => null)
140
    type Thising = (<T>(this: T) => T extends Context ? true : null)
141
142
    const thising = _thising as Thising
143
144
    const suite1 = thising()
145
    , binded = thising.bind({context: ""})
146
    , suite2 = binded()
147
    , suite1Check: Record<string, typeof suite1> = {
148
      "null": null,
149
      //@ts-expect-error
150
      "true": true
151
    }
152
    , suite2Check: Record<string, typeof suite2> = {
153
      //TODO #13 @ts-expect-error
154
      "null": null,
155
      //@ts-expect-error //TODO #13
156
      "true": true
157
    }
158
159
    expect({suite1Check, suite2Check}).toBeInstanceOf(Object)
160
  })
161
162
  it("idfn this", () => {
163
    function thising<T>(this: T) {
164
      return this
165
    }
166
167
    const suite = thising()
168
    , suiteCheck: Record<string, typeof suite> = {
169
      "void": undefined
170
    }
171
172
    expect({suiteCheck}).toBeInstanceOf(Object)
173
  })
174
})
175
176
describe("UX of TS choice", () => {
177
  type T1 = {
178
    class1: string,
179
    class2: undefined
180
  }
181
182
  // it("union", () => {
183
  //   type tUnion<S extends CssModule> = (
184
  //     <A extends {[K in keyof S]?: V}>(source: A) => string
185
  //   ) | (
186
  //     <A extends {[K in keyof S]?: V}>(inject: string, source: A) => string
187
  //   );
188
189
  //   // const str = <S extends CssModule>(arg1: strS) => $keys(source).join(" ")
190
  // })
191
192
  // it("expression 1", () => {
193
  //   type tExpression1<S extends CssModule> = (
194
  //     <A extends {[K in keyof S]?: V}>(arg0: string|A, arg1?: typeof arg0 extends string ? A : never) => string
195
  //   );
196
  // })
197
198
  // it("overload interface", () => {
199
  //   interface iOverload<S extends CssModule> {
200
  //     <A extends {[K in keyof S]?: V}>(arg0: string): string
201
  //     <A extends {[K in keyof S]?: V}>(arg0: string, arg1: A): string
202
  //   }
203
  // })
204
205
  it("overload function", () => {
206
    function joiner<S extends CssModule>(source: {[K in keyof S]?: ClassHash}) :string
207
    function joiner<S extends CssModule>(inj: string, source: {[K in keyof S]?: ClassHash}) :string
208
    function joiner<S extends CssModule, F1 extends {[K in keyof S]?: ClassHash} | string>(
209
      arg0: F1,
210
      // arg1?: typeof arg0 extends string ? {[K in keyof S]?: V} : never
211
      arg1?: F1 extends string ? Exclude<F1, string> : never
212
    ) {
213
      return `${
214
        typeof arg0 === "string" ? arg0 : $keys(arg0)
215
      } ${
216
        arg1 === undefined ? "" : $keys(arg1).join(" ")
217
      }`.trim()
218
    }
219
220
    const bothObjects = joiner<T1>(
221
      //@ts-expect-error Argument of type '{ class1: string; }' is not assignable to parameter of type 'string'
222
      {class1: ""},
223
      {class2: ""}
224
    )
225
    , redundantKey = joiner<T1>(
226
      //@ts-expect-error Argument of type '{ class3: string; }' is not assignable
227
      {class3: ""}
228
    )
229
230
    expect({bothObjects, redundantKey}).toBeInstanceOf(Object)
231
  })
232
})
233
234
describe("keys hinting", () => {
235
  type Source = {
236
    class1: ClassHash
237
    class2: ClassHash
238
    class3: ClassHash
239
  }
240
241
  it("- partial", () => {
242
    const partial = <T extends {[K in keyof Source]?: Action}>(pay: T) => pay
243
    , $return = partial({class1: true, class2: true, class4: undefined})
244
    , check: Record<string, typeof $return> = {
245
      //@ts-expect-error
246
      "missed": {
247
        class1: true, class2: true
248
      },
249
      "exact": {
250
        class1: true, class2: true, class4: undefined
251
      }
252
    }
253
254
    expect(check).toBeInstanceOf(Object)
255
  })
256
257
  it("- partial*pick", () => {
258
    const partial = <T extends {[K in keyof Source]?: Action}>(pay: Pick<T, keyof Source>) => pay
259
    , checkRedundant = partial({class1: true, class2: true,
260
        //@ts-expect-error
261
        class4: undefined
262
      })
263
    , $return = partial({class1: true, class2: true})
264
    , check: Record<string, typeof $return> = {
265
      "exact": {},
266
    }
267
268
    expect({check, checkRedundant}).toBeInstanceOf(Object)
269
  })
270
271
  it("+ partial*own pick", () => {
272
    type Parter<Source> = <
273
      T extends {[K in keyof Source]?: Action}
274
    >(
275
      pay?: T & {[K in keyof T]: K extends keyof Source ? Action : never} | Falsy
276
    ) => T
277
278
    const partial: Parter<Source> = (pay) => pay as any
279
    , checkRedundant = partial({class1: true, class2: true,
280
        //@ts-expect-error
281
        class4: undefined
282
      })
283
    , $return = partial({class1: true, class2: true })
284
    , check: Record<string, typeof $return> = {
285
      //@ts-expect-error
286
      "missed": {class1: true},
287
      "exact": {class1: true, class2: true},
288
      "redundant": {class1: true, class2: true,
289
        //@ts-expect-error
290
        class3: true
291
      },
292
    }
293
294
    expect({check, checkRedundant}).toBeInstanceOf(Object)
295
  })
296
})
297