Comprehensive TypeScript guidance covering compiler configuration, advanced types, utility types, type guards, strict mode workflows, and documentation patterns; use when configuring tsconfig, designing complex generics, making illegal states unrepresentable, fixing type errors, or writing testable and maintainable type-safe APIs.
Overall
score
99%
Does it follow best practices?
Validation for skill structure
TypeScript uses different strategies to locate module files.
For Node.js projects with ESM support:
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext"
}
}Behavior:
package.json "type": "module" or "type": "commonjs".js, .mjs, .cjs// Must include .js extension (not .ts)
import { helper } from "./utils.js";
import type { User } from "./types.js";For projects using bundlers (Vite, esbuild, Webpack):
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler"
}
}Behavior:
"exports" field// Extensions optional
import { helper } from "./utils";
import { Component } from "my-library";Legacy Node.js resolution (not recommended for new projects):
{
"compilerOptions": {
"moduleResolution": "node"
}
}Map module names to locations:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@/*": ["./*"],
"@components/*": ["./components/*"],
"@utils/*": ["./utils/*"],
"@types": ["./types/index.ts"]
}
}
}Usage:
import { Button } from "@components/Button";
import { formatDate } from "@utils/date";
import type { User } from "@types";Important: Build tools need separate configuration
vite.config.ts with resolve.aliaswebpack.config.js with resolve.aliasjest.config.js with moduleNameMapperTreat multiple directories as a single root:
{
"compilerOptions": {
"rootDirs": ["src", "generated"]
}
}Use case: Import from generated code as if it's in source
Modern JavaScript modules:
// Export
export const value = 42;
export function helper() {}
export default class MyClass {}
// Import
import MyClass, { value, helper } from "./module";
import * as Module from "./module";
import type { MyType } from "./module";Node.js traditional modules:
// Export
exports.value = 42;
module.exports = { value: 42 };
// Import
const { value } = require("./module");
const Module = require("./module");Explicitly mark type imports for better tree-shaking:
// Type-only import
import type { User, Post } from "./types";
import { type User, fetchUser } from "./api"; // Mixed
// Type-only export
export type { User, Post };
export { type User, fetchUser }; // MixedBenefits:
isolatedModules and verbatimModuleSyntaxModern packages use "exports" field:
{
"name": "my-library",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./utils": {
"types": "./dist/utils.d.ts",
"import": "./dist/utils.js"
}
}
}Import paths:
import { main } from "my-library";
import { helper } from "my-library/utils";{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": false
}
}declaration: Generate .d.ts filesdeclarationMap: Generate .d.ts.map for "Go to Definition"emitDeclarationOnly: Only emit declarations (useful with Babel)TypeScript looks for types in this order:
package.json "types" or "typings" fieldindex.d.ts in package root@types/<package> package{
"name": "my-library",
"types": "./dist/index.d.ts",
"main": "./dist/index.js"
}// packages/shared/tsconfig.json
{
"compilerOptions": {
"composite": true,
"declaration": true,
"declarationMap": true,
"outDir": "dist"
}
}// packages/app/tsconfig.json
{
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "../shared" }
]
}// packages/app/src/index.ts
import { helper } from "@my-org/shared";Benefits:
bundler for bundled apps - Most flexibleNodeNext for Node.js libraries - Correct ESM/CJS handlingisolatedModules - Ensures transpiler compatibility"exports" in package.json - For librariesInstall with Tessl CLI
npx tessl i pantheon-ai/typescript-advancedreferences