Avoid non-null assertion operator (!) and use type-safe alternatives instead
Detects and replaces deprecated non-null assertion operators (!) with type-safe alternatives like optional chaining (?.), nullish coalescing (??), and proper type guards. Claude uses this when encountering ! operators in TypeScript code to prevent runtime errors and maintain type safety.
/plugin marketplace add djankies/claude-configs/plugin install typescript@claude-configsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
The non-null assertion operator (!) is deprecated in modern TypeScript because it bypasses type safety and can lead to runtime errors.
!undefined or null errors at runtime?.)Bad:
const userName = user!.profile!.name;
Good:
const userName = user?.profile?.name;
??)Bad:
const value = config!.timeout;
Good:
const value = config?.timeout ?? 5000;
Bad:
function processUser(user: User | null) {
console.log(user!.name);
}
Good:
function processUser(user: User | null) {
if (user !== null) {
console.log(user.name);
}
}
Bad:
function getUserEmail(userId: number): string {
const user = findUser(userId);
return user!.email;
}
Good:
function getUserEmail(userId: number): string | null {
const user = findUser(userId);
if (!user) {
return null;
}
return user.email;
}
Bad:
function handleValue(value: unknown) {
return (value as User)!.name;
}
Good:
function isUser(value: unknown): value is User {
return typeof value === 'object' && value !== null && 'name' in value;
}
function handleValue(value: unknown) {
if (isUser(value)) {
return value.name;
}
throw new Error('Invalid user');
}
in OperatorBad:
function process(obj: { data?: string }) {
console.log(obj.data!.toUpperCase());
}
Good:
function process(obj: { data?: string }) {
if ('data' in obj && obj.data !== undefined) {
console.log(obj.data.toUpperCase());
}
}
Bad:
const users: User[] = getUsers();
const firstUser = users[0]!;
Good:
const users: User[] = getUsers();
const firstUser = users.at(0);
if (firstUser) {
console.log(firstUser.name);
}
Good:
function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
if (value === undefined || value === null) {
throw new Error('Value must be defined');
}
}
function process(value: string | null) {
assertIsDefined(value);
console.log(value.toUpperCase());
}
Bad:
const button = document.getElementById('submit')!;
button.addEventListener('click', handler);
Good:
const button = document.getElementById('submit');
if (button) {
button.addEventListener('click', handler);
}
Or with assertion function:
function assertElement<T extends Element>(
element: T | null,
selector: string
): asserts element is T {
if (!element) {
throw new Error(`Element not found: ${selector}`);
}
}
const button = document.getElementById('submit');
assertElement(button, '#submit');
button.addEventListener('click', handler);
! Acceptable?Only in very rare cases where:
Even then, prefer assertion functions over !.
! in codebaseEnable strict checks:
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true,
"noUncheckedIndexedAccess": true
}
}
Never use ! operator:
?. for optional chaining?? for default valuesThis skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.