From harness-claude
Tests TypeScript types at compile time using vitest expectTypeOf, expect-type, tsd, and assertions. Verifies utility types, generics, APIs, and regressions.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Test TypeScript types at compile time using expect-type, tsd, and vitest type matchers
Provides expert TypeScript guidance for type-safe apps, advanced types, strict mode, JS-to-TS refactoring, tsconfig optimization, and TDD workflows.
Provides TypeScript testing patterns using Vitest for unit tests, MSW for API mocking, typed mocks for dependency injection, and snapshot testing.
Masters TypeScript advanced types including generics, conditional types, mapped types, template literals, and utility types for type-safe applications. Use for complex type logic, reusable utilities, and compile-time safety in TS projects.
Share bugs, ideas, or general feedback.
Test TypeScript types at compile time using expect-type, tsd, and vitest type matchers
expectTypeOf from vitest (built-in, no extra dependencies):import { expectTypeOf, test } from 'vitest';
test('User type has correct shape', () => {
expectTypeOf<User>().toMatchTypeOf<{
id: string;
name: string;
email: string;
}>();
});
test('createUser returns User', () => {
expectTypeOf(createUser).returns.toMatchTypeOf<User>();
expectTypeOf(createUser).parameters.toEqualTypeOf<[name: string, email: string]>();
});
test('identity preserves literal types', () => {
const result = identity('hello');
expectTypeOf(result).toEqualTypeOf<'hello'>();
});
test('UserId and PostId are not interchangeable', () => {
expectTypeOf<UserId>().not.toEqualTypeOf<PostId>();
expectTypeOf<UserId>().not.toMatchTypeOf<PostId>();
});
expect-type library for standalone type tests:import { expectTypeOf } from 'expect-type';
// In a .test-d.ts file or regular test file
expectTypeOf<Pick<User, 'id' | 'name'>>().toEqualTypeOf<{
id: string;
name: string;
}>();
expectTypeOf<Partial<User>>().toMatchTypeOf<{ id?: string }>();
tsd for declaration file testing:// test-d.ts
import { expectType, expectError } from 'tsd';
import { createUser } from './index';
expectType<User>(createUser('Alice', 'alice@test.com'));
expectError(createUser(123)); // Should fail with number input
Run with npx tsd in package.json.
test('UnwrapPromise extracts inner type', () => {
expectTypeOf<UnwrapPromise<Promise<string>>>().toEqualTypeOf<string>();
expectTypeOf<UnwrapPromise<Promise<Promise<number>>>>().toEqualTypeOf<number>();
expectTypeOf<UnwrapPromise<string>>().toEqualTypeOf<string>();
});
test('Nullable adds null to all properties', () => {
type Input = { name: string; age: number };
type Expected = { name: string | null; age: number | null };
expectTypeOf<Nullable<Input>>().toEqualTypeOf<Expected>();
});
// types.test.ts — checked by tsc, not executed
type Assert<T extends true> = T;
type IsEqual<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false;
type _test1 = Assert<IsEqual<ReturnType<typeof getUser>, Promise<User>>>;
type _test2 = Assert<IsEqual<Parameters<typeof createUser>, [string, string]>>;
Type tests verify that your type-level code (generics, utility types, conditional types) produces the expected types. They catch regressions that runtime tests cannot — a function might work correctly at runtime but accept the wrong types due to an overly permissive generic.
toEqualTypeOf vs toMatchTypeOf:
toEqualTypeOf — exact match. { a: string } does NOT equal { a: string; b?: number }toMatchTypeOf — structural compatibility. { a: string; b: number } MATCHES { a: string }Tool comparison:
expectTypeOf — integrated into vitest, runs alongside runtime tests, best for projects already using vitestexpect-type — standalone library, works with any test runner, same API as vitest's built-intsd — designed for library authors testing .d.ts files, uses a different assertion APIWhen to test types:
When NOT to test types:
Trade-offs:
expectTypeOf assertions run at compile time, not runtime — test files must be type-checked by tschttps://typescriptlang.org/docs/handbook/2/types-from-types.html