Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Language-specific super-code guidelines for typescript.
.claude/skills/lingxling-typescript/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-15 | ✗→✓ | ▲ Improved | 216% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 252% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 456% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 227% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 173% | 0% |
ts// ❌ Imperative push loop const result: string[] = [] for (const item of items) { if (item.active) result.push(item.name.toUpperCase()) } // ✅ const result = items.filter(i => i.active).map(i => i.name.toUpperCase())
ts// ❌ Manual reduce for sum let total = 0 for (const o of orders) total += o.amount // ✅ const total = orders.reduce((sum, o) => sum + o.amount, 0)
ts// ❌ Manual object copy + override const updated = Object.assign({}, user) updated.name = "Alice" // ✅ const updated = { ...user, name: "Alice" }
ts// ❌ Existence check before property access const city = user.address ? user.address.city : undefined // ✅ const city = user.address?.city
ts// ❌ Separate variable assignments const name = user.name const age = user.age // ✅ const { name, age } = user
ts// ❌ Index access for array elements const first = arr[0] const second = arr[1] // ✅ const [first, second] = arr
ts// ❌ Merging arrays with concat const merged = a.concat(b).concat(c) // ✅ const merged = [...a, ...b, ...c]
ts// ❌ Omitting a key by delete (mutates) const copy = { ...obj } delete copy.password // ✅ — destructure to omit const { password, ...safe } = obj
ts// ❌ Promise chain when async/await is cleaner fetchUser(id) .then(user => fetchOrders(user.id)) .then(orders => process(orders)) .catch(handleError) // ✅ try { const user = await fetchUser(id) const orders = await fetchOrders(user.id) process(orders) } catch (e) { handleError(e) }
ts// ❌ Sequential awaits for independent operations const user = await fetchUser(id) const config = await fetchConfig() // ✅ — run in parallel const [user, config] = await Promise.all([fetchUser(id), fetchConfig()])
ts// ❌ Wrapping already-async function in new Promise const result = await new Promise((resolve) => { someAsyncFn().then(resolve) }) // ✅ const result = await someAsyncFn()
Don't await inside a .map() without Promise.all — it sequences what should be parallel.
ts// ❌ Arrow function with unnecessary block body const double = (x: number) => { return x * 2 } // ✅ const double = (x: number) => x * 2
ts// ❌ Default parameter with if-guard function greet(name?: string) { if (!name) name = "World" return `Hello, ${name}` } // ✅ function greet(name = "World") { return `Hello, ${name}` }
ts// ❌ IIFE for no reason in module scope ;(function() { const x = compute() doSomething(x) })() // ✅ — just top-level statements in a module const x = compute() doSomething(x)
ts// ❌ Explicit return type when inference is obvious function add(a: number, b: number): number { return a + b } // ✅ — let TS infer simple return types function add(a: number, b: number) { return a + b }
ts// ❌ any function process(data: any) { ... } // ✅ — use unknown + type guard, or a proper type/generic function process<T extends Record<string, unknown>>(data: T) { ... }
ts// ❌ Redundant interface for single-use inline shape interface UserNameProps { name: string } function UserName({ name }: UserNameProps) { ... } // ✅ — inline for single-use function UserName({ name }: { name: string }) { ... } // Extract interface when reused in 2+ places
ts// ❌ Type assertion (as) to silence a real type error const el = document.getElementById("app") as HTMLDivElement el.innerText = "hi" // crashes if el is null // ✅ const el = document.getElementById("app") if (!(el instanceof HTMLDivElement)) throw new Error("Missing #app") el.innerText = "hi"
Prefer type for unions/intersections/aliases; interface for extensible object shapes.
tsx// ❌ Effect for derived state const [doubled, setDoubled] = useState(0) useEffect(() => { setDoubled(count * 2) }, [count]) // ✅ — compute during render const doubled = count * 2
tsx// ❌ useCallback everywhere by default const handler = useCallback(() => doSomething(id), [id]) // ✅ — only when passed to memoized child or used as effect dep // Otherwise: const handler = () => doSomething(id)
tsx// ❌ Passing object literal as prop (new reference each render) <Component config={{ debug: true }} /> // ✅ const config = useMemo(() => ({ debug: true }), []) <Component config={config} /> // Or if truly static: define outside component const CONFIG = { debug: true }
tsx// ❌ Index as key in list that can reorder/filter items.map((item, i) => <Row key={i} {...item} />) // ✅ items.map(item => <Row key={item.id} {...item} />)
| Anti-pattern | Preferred | |---|---| | == null (loose) | === null or ?? / ?. | | typeof x === "undefined" | x === undefined or x == null (when both null/undefined ok) | | !!x when boolean coercion is implied | Boolean(x) for clarity, or just x in conditionals | | var | const by default, let when reassigned | | for...in on arrays | for...of or array methods | | String template literal with no interpolation | plain string '...' | | console.log left in production code | remove or use a logger | | Object.keys(obj).forEach(...) | for (const [k, v] of Object.entries(obj)) | | Nested ternaries beyond 2 levels | if/else or early return | | try { ... } catch (e) {} (silent swallow) | log or rethrow |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 17,252 | 14,493 | -16% | 1 | 1 | 0% | 3,146 | 4,090 | +30% | 0 | 0 | — |
case-02 | pass→pass | 4,203 | 3,725 | -11% | 1 | 1 | 0% | 705 | 2,302 | +227% | 0 | 0 | — |
case-03 | pass→pass | 7,186 | 4,149 | -42% | 1 | 1 | 0% | 889 | 2,423 | +173% | 0 | 0 | — |
case-04 | pass→pass | 9,222 | 7,270 | -21% | 1 | 1 | 0% | 1,347 | 2,697 | +100% | 0 | 0 | — |
case-05 | pass→pass | 5,932 | 3,840 | -35% | 1 | 1 | 0% | 882 | 2,409 | +173% | 0 | 0 | — |
case-15 | fail→pass | 4,935 | 2,424 | -51% | 1 | 1 | 0% | 717 | 2,267 | +216% | 0 | 0 | — |
case-06 | fail→pass | 5,935 | 4,193 | -29% | 1 | 1 | 0% | 692 | 2,434 | +252% | 0 | 0 | — |
case-07 | pass→pass | 14,645 | 6,652 | -55% | 1 | 1 | 0% | 1,383 | 2,670 | +93% | 0 | 0 | — |
case-08 | pass→pass | 5,545 | 6,128 | +11% | 1 | 1 | 0% | 1,059 | 2,659 | +151% | 0 | 0 | — |
case-09 | pass→pass | 5,505 | 5,590 | +2% | 1 | 1 | 0% | 1,018 | 2,612 | +157% | 0 | 0 | — |
case-10 | pass→pass | 6,325 | 6,844 | +8% | 1 | 1 | 0% | 1,038 | 2,725 | +163% | 0 | 0 | — |
case-11 | pass→pass | 3,480 | 2,419 | -30% | 1 | 1 | 0% | 362 | 2,144 | +492% | 0 | 0 | — |
case-12 | pass→pass | 3,107 | 3,576 | +15% | 1 | 1 | 0% | 548 | 2,314 | +322% | 0 | 0 | — |
case-13 | fail→pass | 2,840 | 2,508 | -12% | 1 | 1 | 0% | 413 | 2,297 | +456% | 0 | 0 | — |
case-14 | pass→pass | 15,702 | 15,005 | -4% | 1 | 1 | 0% | 2,083 | 3,925 | +88% | 0 | 0 | — |
case-16 | fail→fail | 10,242 | 6,508 | -36% | 1 | 1 | 0% | 1,106 | 2,914 | +163% | 0 | 0 | — |
case-17 | pass→pass | 10,497 | 4,779 | -54% | 1 | 1 | 0% | 928 | 2,501 | +170% | 0 | 0 | — |
case-18 | pass→pass | 6,723 | 4,601 | -32% | 1 | 1 | 0% | 1,033 | 2,477 | +140% | 0 | 0 | — |
case-19 | pass→pass | 4,340 | 7,477 | +72% | 1 | 1 | 0% | 678 | 2,905 | +328% | 0 | 0 | — |
case-20 | pass→pass | 3,981 | 3,809 | -4% | 1 | 1 | 0% | 538 | 2,490 | +363% | 0 | 0 | — |
case-21 | pass→pass | 5,093 | 3,752 | -26% | 1 | 1 | 0% | 625 | 2,429 | +289% | 0 | 0 | — |
case-22 | pass→pass | 44,891 | 26,460 | -41% | 1 | 1 | 0% | 8,231 | 6,723 | -18% | 0 | 0 | — |
case-23 | pass→pass | 32,687 | 12,795 | -61% | 1 | 1 | 0% | 2,935 | 4,259 | +45% | 0 | 0 | — |
case-24 | pass→pass | 16,028 | 11,980 | -25% | 1 | 1 | 0% | 3,167 | 4,100 | +29% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.