agentsclimarketplace

Typescript strict

Skill aiskillstore/marketplace/skills/doyajin174/typescript-strict

Enforce TypeScript strict mode and type safety. Use when setting up projects, reviewing code, or when type errors are ignored. Covers strict flags, no-any rules, and type inference best practices.From its SKILL.md

Install
npx -y skills add aiskillstore/marketplace --skill typescript-strict

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

7.4 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it

TypeScript Strict Mode

TypeScript 엄격 모드와 타입 안전성을 강제하는 스킬입니다.

2025 Context

TypeScript 5.x에서 strict 모드가 새 프로젝트의 기본값으로 권장됨 "any 사용은 TypeScript를 쓰는 의미를 없앤다"

Core Rules

규칙상태설명
strict: true🔴 필수모든 엄격 검사 활성화
any 금지🔴 필수unknown 또는 제네릭 사용
// @ts-ignore 금지🔴 필수타입 에러 해결 필수
as 캐스팅 최소화🟡 권장타입 가드 우선

tsconfig.json 권장 설정

{
  "compilerOptions": {
    // 🔴 필수: strict 플래그
    "strict": true,

    // strict가 포함하는 옵션들 (개별 비활성화 금지)
    // "strictNullChecks": true,
    // "strictFunctionTypes": true,
    // "strictBindCallApply": true,
    // "strictPropertyInitialization": true,
    // "noImplicitAny": true,
    // "noImplicitThis": true,
    // "alwaysStrict": true,

    // 🔴 추가 필수 옵션
    "noUncheckedIndexedAccess": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,

    // 🟡 권장 옵션
    "exactOptionalPropertyTypes": true,
    "noPropertyAccessFromIndexSignature": true
  }
}

any 금지

문제: any 사용

// ❌ BAD: any 사용
function processData(data: any) {
  return data.value;  // 런타임 에러 가능
}

const result: any = fetchData();
result.nonExistent();  // 컴파일 통과, 런타임 에러

해결: unknown 또는 타입 명시

// ✅ GOOD: unknown + 타입 가드
function processData(data: unknown) {
  if (isValidData(data)) {
    return data.value;
  }
  throw new Error('Invalid data');
}

function isValidData(data: unknown): data is { value: string } {
  return typeof data === 'object'
    && data !== null
    && 'value' in data;
}

// ✅ GOOD: 제네릭 사용
function processData<T extends { value: string }>(data: T) {
  return data.value;
}

any → unknown 마이그레이션

// Before
function parse(json: string): any {
  return JSON.parse(json);
}

// After
function parse(json: string): unknown {
  return JSON.parse(json);
}

// 사용 시 타입 체크 필요
const result = parse('{"name": "test"}');
if (isUser(result)) {
  console.log(result.name);  // 안전
}

타입 단언(as) 최소화

문제: 과도한 타입 단언

// ❌ BAD: 위험한 타입 단언
const user = response.data as User;
user.name.toUpperCase();  // null이면 에러

// ❌ BAD: 이중 단언 (매우 위험)
const value = data as unknown as TargetType;

해결: 타입 가드 사용

// ✅ GOOD: 타입 가드
function isUser(data: unknown): data is User {
  return (
    typeof data === 'object' &&
    data !== null &&
    'name' in data &&
    typeof (data as { name: unknown }).name === 'string'
  );
}

if (isUser(response.data)) {
  response.data.name.toUpperCase();  // 안전
}

// ✅ GOOD: Zod 스키마 검증
import { z } from 'zod';

const UserSchema = z.object({
  name: z.string(),
  email: z.string().email(),
});

const user = UserSchema.parse(response.data);

Null 안전성

strictNullChecks 활용

// ❌ BAD: null 체크 없음
function getLength(str: string | null) {
  return str.length;  // 에러: null일 수 있음
}

// ✅ GOOD: null 체크
function getLength(str: string | null) {
  if (str === null) return 0;
  return str.length;
}

// ✅ GOOD: 옵셔널 체이닝
function getLength(str: string | null) {
  return str?.length ?? 0;
}

배열 인덱스 접근

// noUncheckedIndexedAccess: true 일 때

const arr = [1, 2, 3];
const first = arr[0];  // number | undefined

// ❌ BAD: undefined 체크 없음
console.log(first.toFixed(2));  // 에러

// ✅ GOOD: undefined 체크
if (first !== undefined) {
  console.log(first.toFixed(2));
}

// ✅ GOOD: 논리 연산자
console.log(arr[0]?.toFixed(2) ?? 'N/A');

함수 타입

반환 타입 명시 (권장)

// ❌ BAD: 반환 타입 추론 의존
function fetchUser(id: string) {
  return api.get(`/users/${id}`);  // 반환 타입?
}

// ✅ GOOD: 명시적 반환 타입
async function fetchUser(id: string): Promise<User> {
  return api.get(`/users/${id}`);
}

함수 오버로드

// ✅ GOOD: 오버로드로 정확한 타입
function process(input: string): string;
function process(input: number): number;
function process(input: string | number): string | number {
  if (typeof input === 'string') {
    return input.toUpperCase();
  }
  return input * 2;
}

const str = process('hello');  // string
const num = process(42);       // number

제네릭 활용

// ❌ BAD: any 사용
function first(arr: any[]): any {
  return arr[0];
}

// ✅ GOOD: 제네릭
function first<T>(arr: T[]): T | undefined {
  return arr[0];
}

// ✅ GOOD: 제약 있는 제네릭
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

ESLint 규칙

{
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking"
  ],
  "rules": {
    "@typescript-eslint/no-explicit-any": "error",
    "@typescript-eslint/no-unsafe-assignment": "error",
    "@typescript-eslint/no-unsafe-member-access": "error",
    "@typescript-eslint/no-unsafe-call": "error",
    "@typescript-eslint/no-unsafe-return": "error",
    "@typescript-eslint/explicit-function-return-type": "warn",
    "@typescript-eslint/no-non-null-assertion": "warn",
    "@typescript-eslint/prefer-nullish-coalescing": "warn"
  }
}

금지 패턴

// 🔴 절대 금지
// @ts-ignore
// @ts-nocheck
// @ts-expect-error (테스트 제외)
// eslint-disable @typescript-eslint/no-explicit-any

// 🔴 금지: any 캐스팅
data as any
(data as unknown) as TargetType

// 🟡 최소화
data!  // non-null assertion
data as Type  // 타입 가드 우선

Workflow

1. 새 프로젝트 설정

# TypeScript 초기화
npx tsc --init

# strict 활성화 확인
grep -n "strict" tsconfig.json

2. 기존 프로젝트 마이그레이션

# 1. strict 활성화
# tsconfig.json: "strict": true

# 2. 에러 확인
npx tsc --noEmit

# 3. 점진적 수정
# - any → unknown
# - as → 타입 가드
# - null 체크 추가

3. 코드 리뷰 체크

타입 안전성 체크:
- [ ] any 사용하지 않음
- [ ] @ts-ignore 없음
- [ ] 타입 단언 최소화
- [ ] null 체크 적절함

Checklist

  • strict: true 설정
  • noUncheckedIndexedAccess: true 설정
  • ESLint @typescript-eslint 규칙 적용
  • any 0개
  • @ts-ignore 0개
  • 타입 가드 함수 구현
  • 명시적 반환 타입 (공개 API)

References

What ships with it: 1 file

41.8 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.