skillshop 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +217 -104
- package/agents-content/000_communication-writing.block.md +11 -0
- package/agents-content/001_external-actions.block.md +9 -0
- package/agents-content/AGENTS.md +11 -0
- package/package.json +6 -3
- package/skills-content/architecture-scanner/SKILL.md +274 -0
- package/skills-content/architecture-scanner/files.json +10 -0
- package/skills-content/architecture-scanner/scan.sh +823 -0
- package/skills-content/change-review/SKILL.md +76 -0
- package/skills-content/change-review/agents/openai.yaml +4 -0
- package/skills-content/changelog/SKILL.md +99 -0
- package/skills-content/changeset/changeset.md +80 -0
- package/skills-content/code-buddy/SKILL.md +136 -0
- package/skills-content/design-system-catalog/SKILL.md +106 -0
- package/skills-content/design-system-catalog/extract-components.mjs +441 -0
- package/skills-content/design-system-catalog/generate-catalog.sh +255 -0
- package/skills-content/flare/SKILL.md +96 -0
- package/skills-content/grilling/SKILL.md +31 -0
- package/skills-content/install-sigmap/SKILL.md +97 -0
- package/skills-content/one-shot/SKILL.md +51 -0
- package/skills-content/release/SKILL.md +128 -0
- package/skills-content/shadow-clone/SKILL.md +228 -0
- package/skills-content/shadow-clone/extract-signatures.mjs +202 -0
- package/skills-content/shadow-clone/scan-repo.mjs +343 -0
- package/skills-content/ship/SKILL.md +95 -0
- package/skills-content/shots/SKILL.md +89 -0
- package/skills-content/shots/agents/openai.yaml +4 -0
- package/skills-content/skillshop/SKILL.md +104 -0
- package/skills-content/skillz/SKILL.md +15 -0
- package/skills-content/transcript-clean/SKILL.md +55 -0
- package/skills-content/transcript-edit/SKILL.md +80 -0
- package/skills-content/vitest/GENERATION.md +5 -0
- package/skills-content/vitest/SKILL.md +52 -0
- package/skills-content/vitest/references/advanced-environments.md +264 -0
- package/skills-content/vitest/references/advanced-projects.md +300 -0
- package/skills-content/vitest/references/advanced-type-testing.md +237 -0
- package/skills-content/vitest/references/advanced-vi.md +249 -0
- package/skills-content/vitest/references/core-cli.md +166 -0
- package/skills-content/vitest/references/core-config.md +174 -0
- package/skills-content/vitest/references/core-describe.md +193 -0
- package/skills-content/vitest/references/core-expect.md +219 -0
- package/skills-content/vitest/references/core-hooks.md +244 -0
- package/skills-content/vitest/references/core-test-api.md +233 -0
- package/skills-content/vitest/references/features-concurrency.md +250 -0
- package/skills-content/vitest/references/features-context.md +238 -0
- package/skills-content/vitest/references/features-coverage.md +207 -0
- package/skills-content/vitest/references/features-filtering.md +211 -0
- package/skills-content/vitest/references/features-mocking.md +265 -0
- package/skills-content/vitest/references/features-snapshots.md +207 -0
- package/skills-content/workleaf/SKILL.md +77 -0
- package/skills-content/worklog/SKILL.md +145 -0
- package/skills-content/worklog/references/summary-format.md +114 -0
- package/skills-content/worktree/SKILL.md +71 -0
- package/src/agents-instructions.js +219 -0
- package/src/cli.js +87 -23
- package/src/import.js +12 -7
- package/src/index.js +1 -0
- package/src/legacy-agents-content.js +36 -0
- package/src/legacy-cli.js +1234 -0
- package/src/library.js +9 -0
- package/src/specifier.js +11 -0
- package/src/user-install.js +48 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: projects-workspaces
|
|
3
|
+
description: Multi-project configuration for monorepos and different test types
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Projects
|
|
7
|
+
|
|
8
|
+
Run different test configurations in the same Vitest process.
|
|
9
|
+
|
|
10
|
+
## Basic Projects Setup
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
// vitest.config.ts
|
|
14
|
+
defineConfig({
|
|
15
|
+
test: {
|
|
16
|
+
projects: [
|
|
17
|
+
// Glob patterns for config files
|
|
18
|
+
'packages/*',
|
|
19
|
+
|
|
20
|
+
// Inline config
|
|
21
|
+
{
|
|
22
|
+
test: {
|
|
23
|
+
name: 'unit',
|
|
24
|
+
include: ['tests/unit/**/*.test.ts'],
|
|
25
|
+
environment: 'node',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
test: {
|
|
30
|
+
name: 'integration',
|
|
31
|
+
include: ['tests/integration/**/*.test.ts'],
|
|
32
|
+
environment: 'jsdom',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Monorepo Pattern
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
defineConfig({
|
|
44
|
+
test: {
|
|
45
|
+
projects: [
|
|
46
|
+
// Each package has its own vitest.config.ts
|
|
47
|
+
'packages/core',
|
|
48
|
+
'packages/cli',
|
|
49
|
+
'packages/utils',
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Package config:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// packages/core/vitest.config.ts
|
|
59
|
+
import { defineConfig } from 'vitest/config'
|
|
60
|
+
|
|
61
|
+
export default defineConfig({
|
|
62
|
+
test: {
|
|
63
|
+
name: 'core',
|
|
64
|
+
include: ['src/**/*.test.ts'],
|
|
65
|
+
environment: 'node',
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Different Environments
|
|
71
|
+
|
|
72
|
+
Run same tests in different environments:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
defineConfig({
|
|
76
|
+
test: {
|
|
77
|
+
projects: [
|
|
78
|
+
{
|
|
79
|
+
test: {
|
|
80
|
+
name: 'happy-dom',
|
|
81
|
+
root: './shared-tests',
|
|
82
|
+
environment: 'happy-dom',
|
|
83
|
+
setupFiles: ['./setup.happy-dom.ts'],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
test: {
|
|
88
|
+
name: 'node',
|
|
89
|
+
root: './shared-tests',
|
|
90
|
+
environment: 'node',
|
|
91
|
+
setupFiles: ['./setup.node.ts'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Browser + Node Projects
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
defineConfig({
|
|
103
|
+
test: {
|
|
104
|
+
projects: [
|
|
105
|
+
{
|
|
106
|
+
test: {
|
|
107
|
+
name: 'unit',
|
|
108
|
+
include: ['tests/unit/**/*.test.ts'],
|
|
109
|
+
environment: 'node',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
test: {
|
|
114
|
+
name: 'browser',
|
|
115
|
+
include: ['tests/browser/**/*.test.ts'],
|
|
116
|
+
browser: {
|
|
117
|
+
enabled: true,
|
|
118
|
+
name: 'chromium',
|
|
119
|
+
provider: 'playwright',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Shared Configuration
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// vitest.shared.ts
|
|
132
|
+
export const sharedConfig = {
|
|
133
|
+
testTimeout: 10000,
|
|
134
|
+
setupFiles: ['./tests/setup.ts'],
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// vitest.config.ts
|
|
138
|
+
import { sharedConfig } from './vitest.shared'
|
|
139
|
+
|
|
140
|
+
defineConfig({
|
|
141
|
+
test: {
|
|
142
|
+
projects: [
|
|
143
|
+
{
|
|
144
|
+
test: {
|
|
145
|
+
...sharedConfig,
|
|
146
|
+
name: 'unit',
|
|
147
|
+
include: ['tests/unit/**/*.test.ts'],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
test: {
|
|
152
|
+
...sharedConfig,
|
|
153
|
+
name: 'e2e',
|
|
154
|
+
include: ['tests/e2e/**/*.test.ts'],
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Project-Specific Dependencies
|
|
163
|
+
|
|
164
|
+
Each project can have different dependencies inlined:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
defineConfig({
|
|
168
|
+
test: {
|
|
169
|
+
projects: [
|
|
170
|
+
{
|
|
171
|
+
test: {
|
|
172
|
+
name: 'project-a',
|
|
173
|
+
server: {
|
|
174
|
+
deps: {
|
|
175
|
+
inline: ['package-a'],
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Running Specific Projects
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Run specific project
|
|
189
|
+
vitest --project unit
|
|
190
|
+
vitest --project integration
|
|
191
|
+
|
|
192
|
+
# Multiple projects
|
|
193
|
+
vitest --project unit --project e2e
|
|
194
|
+
|
|
195
|
+
# Exclude project
|
|
196
|
+
vitest --project.ignore browser
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Providing Values to Projects
|
|
200
|
+
|
|
201
|
+
Share values from config to tests:
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
// vitest.config.ts
|
|
205
|
+
defineConfig({
|
|
206
|
+
test: {
|
|
207
|
+
projects: [
|
|
208
|
+
{
|
|
209
|
+
test: {
|
|
210
|
+
name: 'staging',
|
|
211
|
+
provide: {
|
|
212
|
+
apiUrl: 'https://staging.api.com',
|
|
213
|
+
debug: true,
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
test: {
|
|
219
|
+
name: 'production',
|
|
220
|
+
provide: {
|
|
221
|
+
apiUrl: 'https://api.com',
|
|
222
|
+
debug: false,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
// In tests, use inject
|
|
231
|
+
import { inject } from 'vitest'
|
|
232
|
+
|
|
233
|
+
test('uses correct api', () => {
|
|
234
|
+
const url = inject('apiUrl')
|
|
235
|
+
expect(url).toContain('api.com')
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## With Fixtures
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const test = base.extend({
|
|
243
|
+
apiUrl: ['/default', { injected: true }],
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
test('uses injected url', ({ apiUrl }) => {
|
|
247
|
+
// apiUrl comes from project's provide config
|
|
248
|
+
})
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Project Isolation
|
|
252
|
+
|
|
253
|
+
Each project runs in its own thread pool by default:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
defineConfig({
|
|
257
|
+
test: {
|
|
258
|
+
projects: [
|
|
259
|
+
{
|
|
260
|
+
test: {
|
|
261
|
+
name: 'isolated',
|
|
262
|
+
isolate: true, // Full isolation
|
|
263
|
+
pool: 'forks',
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Global Setup per Project
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
defineConfig({
|
|
275
|
+
test: {
|
|
276
|
+
projects: [
|
|
277
|
+
{
|
|
278
|
+
test: {
|
|
279
|
+
name: 'with-db',
|
|
280
|
+
globalSetup: ['./tests/db-setup.ts'],
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
},
|
|
285
|
+
})
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Key Points
|
|
289
|
+
|
|
290
|
+
- Projects run in same Vitest process
|
|
291
|
+
- Each project can have different environment, config
|
|
292
|
+
- Use glob patterns for monorepo packages
|
|
293
|
+
- Run specific projects with `--project` flag
|
|
294
|
+
- Use `provide` to inject config values into tests
|
|
295
|
+
- Projects inherit from root config unless overridden
|
|
296
|
+
|
|
297
|
+
<!--
|
|
298
|
+
Source references:
|
|
299
|
+
- https://vitest.dev/guide/projects.html
|
|
300
|
+
-->
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: type-testing
|
|
3
|
+
description: Test TypeScript types with expectTypeOf and assertType
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Type Testing
|
|
7
|
+
|
|
8
|
+
Test TypeScript types without runtime execution.
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
Type tests use `.test-d.ts` extension:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
// math.test-d.ts
|
|
16
|
+
import { expectTypeOf } from 'vitest'
|
|
17
|
+
import { add } from './math'
|
|
18
|
+
|
|
19
|
+
test('add returns number', () => {
|
|
20
|
+
expectTypeOf(add).returns.toBeNumber()
|
|
21
|
+
})
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
defineConfig({
|
|
28
|
+
test: {
|
|
29
|
+
typecheck: {
|
|
30
|
+
enabled: true,
|
|
31
|
+
|
|
32
|
+
// Only type check
|
|
33
|
+
only: false,
|
|
34
|
+
|
|
35
|
+
// Checker: 'tsc' or 'vue-tsc'
|
|
36
|
+
checker: 'tsc',
|
|
37
|
+
|
|
38
|
+
// Include patterns
|
|
39
|
+
include: ['**/*.test-d.ts'],
|
|
40
|
+
|
|
41
|
+
// tsconfig to use
|
|
42
|
+
tsconfig: './tsconfig.json',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## expectTypeOf API
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { expectTypeOf } from 'vitest'
|
|
52
|
+
|
|
53
|
+
// Basic type checks
|
|
54
|
+
expectTypeOf<string>().toBeString()
|
|
55
|
+
expectTypeOf<number>().toBeNumber()
|
|
56
|
+
expectTypeOf<boolean>().toBeBoolean()
|
|
57
|
+
expectTypeOf<null>().toBeNull()
|
|
58
|
+
expectTypeOf<undefined>().toBeUndefined()
|
|
59
|
+
expectTypeOf<void>().toBeVoid()
|
|
60
|
+
expectTypeOf<never>().toBeNever()
|
|
61
|
+
expectTypeOf<any>().toBeAny()
|
|
62
|
+
expectTypeOf<unknown>().toBeUnknown()
|
|
63
|
+
expectTypeOf<object>().toBeObject()
|
|
64
|
+
expectTypeOf<Function>().toBeFunction()
|
|
65
|
+
expectTypeOf<[]>().toBeArray()
|
|
66
|
+
expectTypeOf<symbol>().toBeSymbol()
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Value Type Checking
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const value = 'hello'
|
|
73
|
+
expectTypeOf(value).toBeString()
|
|
74
|
+
|
|
75
|
+
const obj = { name: 'test', count: 42 }
|
|
76
|
+
expectTypeOf(obj).toMatchTypeOf<{ name: string }>()
|
|
77
|
+
expectTypeOf(obj).toHaveProperty('name')
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Function Types
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
function greet(name: string): string {
|
|
84
|
+
return `Hello, ${name}`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
expectTypeOf(greet).toBeFunction()
|
|
88
|
+
expectTypeOf(greet).parameters.toEqualTypeOf<[string]>()
|
|
89
|
+
expectTypeOf(greet).returns.toBeString()
|
|
90
|
+
|
|
91
|
+
// Parameter checking
|
|
92
|
+
expectTypeOf(greet).parameter(0).toBeString()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Object Types
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
interface User {
|
|
99
|
+
id: number
|
|
100
|
+
name: string
|
|
101
|
+
email?: string
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
expectTypeOf<User>().toHaveProperty('id')
|
|
105
|
+
expectTypeOf<User>().toHaveProperty('name').toBeString()
|
|
106
|
+
|
|
107
|
+
// Check shape
|
|
108
|
+
expectTypeOf({ id: 1, name: 'test' }).toMatchTypeOf<User>()
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Equality vs Matching
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
interface A { x: number }
|
|
115
|
+
interface B { x: number; y: string }
|
|
116
|
+
|
|
117
|
+
// toMatchTypeOf - subset matching
|
|
118
|
+
expectTypeOf<B>().toMatchTypeOf<A>() // B extends A
|
|
119
|
+
|
|
120
|
+
// toEqualTypeOf - exact match
|
|
121
|
+
expectTypeOf<A>().not.toEqualTypeOf<B>() // Not exact match
|
|
122
|
+
expectTypeOf<A>().toEqualTypeOf<{ x: number }>() // Exact match
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Branded Types
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
type UserId = number & { __brand: 'UserId' }
|
|
129
|
+
type PostId = number & { __brand: 'PostId' }
|
|
130
|
+
|
|
131
|
+
expectTypeOf<UserId>().not.toEqualTypeOf<PostId>()
|
|
132
|
+
expectTypeOf<UserId>().not.toEqualTypeOf<number>()
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Generic Types
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
function identity<T>(value: T): T {
|
|
139
|
+
return value
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
expectTypeOf(identity<string>).returns.toBeString()
|
|
143
|
+
expectTypeOf(identity<number>).returns.toBeNumber()
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Nullable Types
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
type MaybeString = string | null | undefined
|
|
150
|
+
|
|
151
|
+
expectTypeOf<MaybeString>().toBeNullable()
|
|
152
|
+
expectTypeOf<string>().not.toBeNullable()
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## assertType
|
|
156
|
+
|
|
157
|
+
Assert a value matches a type (no assertion at runtime):
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { assertType } from 'vitest'
|
|
161
|
+
|
|
162
|
+
function getUser(): User | null {
|
|
163
|
+
return { id: 1, name: 'test' }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
test('returns user', () => {
|
|
167
|
+
const result = getUser()
|
|
168
|
+
|
|
169
|
+
// @ts-expect-error - should fail type check
|
|
170
|
+
assertType<string>(result)
|
|
171
|
+
|
|
172
|
+
// Correct type
|
|
173
|
+
assertType<User | null>(result)
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Using @ts-expect-error
|
|
178
|
+
|
|
179
|
+
Test that code produces type error:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
test('rejects wrong types', () => {
|
|
183
|
+
function requireString(s: string) {}
|
|
184
|
+
|
|
185
|
+
// @ts-expect-error - number not assignable to string
|
|
186
|
+
requireString(123)
|
|
187
|
+
})
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Running Type Tests
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Run type tests
|
|
194
|
+
vitest typecheck
|
|
195
|
+
|
|
196
|
+
# Run alongside unit tests
|
|
197
|
+
vitest --typecheck
|
|
198
|
+
|
|
199
|
+
# Type tests only
|
|
200
|
+
vitest --typecheck.only
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Mixed Test Files
|
|
204
|
+
|
|
205
|
+
Combine runtime and type tests:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
// user.test.ts
|
|
209
|
+
import { describe, expect, expectTypeOf, test } from 'vitest'
|
|
210
|
+
import { createUser } from './user'
|
|
211
|
+
|
|
212
|
+
describe('createUser', () => {
|
|
213
|
+
test('runtime: creates user', () => {
|
|
214
|
+
const user = createUser('John')
|
|
215
|
+
expect(user.name).toBe('John')
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
test('types: returns User type', () => {
|
|
219
|
+
expectTypeOf(createUser).returns.toMatchTypeOf<{ name: string }>()
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Key Points
|
|
225
|
+
|
|
226
|
+
- Use `.test-d.ts` for type-only tests
|
|
227
|
+
- `expectTypeOf` for type assertions
|
|
228
|
+
- `toMatchTypeOf` for subset matching
|
|
229
|
+
- `toEqualTypeOf` for exact type matching
|
|
230
|
+
- Use `@ts-expect-error` to test type errors
|
|
231
|
+
- Run with `vitest typecheck` or `--typecheck`
|
|
232
|
+
|
|
233
|
+
<!--
|
|
234
|
+
Source references:
|
|
235
|
+
- https://vitest.dev/guide/testing-types.html
|
|
236
|
+
- https://vitest.dev/api/expect-typeof.html
|
|
237
|
+
-->
|