AI Skill Report Card
Applying TypeScript Coding Standards
Quick Start14 / 15
When writing or reviewing TypeScript code, check against these rules in order of priority: 强制 (mandatory) rules must never be violated; 推荐 (recommended) rules should be followed unless there's a documented reason not to.
TypeScript// Mandatory checks const foo = 'bar' as string; // not <string>'bar' const foo2 = { x: 1 } as MyType; // object literals: use `as`, not <T> class Foo { foo(s: string): void; // overloads adjacent foo(n: number): void; foo(sn: string | number): void {} } type Foo = { name: string; greet(): void }; // `;` delimiter let x: string = 'bar'; // space after colon // Recommended checks interface Point { x: number; y: number } // prefer interface over type for objects const arr: string[] = ['a']; // simple type -> T[] const arr2: Array<{ id: string }> = []; // complex type -> Array<T>
Recommendation▾
Add a 'bad outcome' example showing a fully non-compliant code block reviewed end-to-end, not just isolated fixes, to reinforce real-world review scenarios.
Workflow14 / 15
Progress checklist when reviewing/writing TS code:
- Confirm underlying JS spec is followed first (this spec only covers TS-specific additions)
- Check type assertions use
as Type, never<Type>, never on object literals (exceptany/unknown) - Check array type style:
T[]for primitives,Array<T>for complex/union/object/function types - Check interface/type member delimiter is
;, spacing around:and=>is correct - Check member ordering: static > instance, field > constructor > method, public > protected > private
- Check overloaded function/method signatures are grouped together
- Check accessibility modifiers are explicit for non-public members (private/protected)
- Check no
namespace/moduleused for runtime code (only allowed indeclarecontexts) - Check no
require(), prefer ES2015import - Check no redundant type annotations when inference already narrows the type
- Check
// @ts-ignore/// @ts-expect-erroralways has explanatory comment - Check no dangling
thisalias (const self = this), prefer arrow functions - Check
+operator operands are both numbers or both strings (no implicit coercion) - Check string literals use single quotes
- Check no triple-slash
///references outside.d.tsfiles - Check empty interfaces are removed/merged
- Check
as constused when value equals a literal type declaration
Recommendation▾
Include a brief note on how to configure/extend eslint-config-ali/typescript in a project (e.g., .eslintrc snippet) since the skill references it as a best practice.
Rule Reference (grouped by enforcement level)
Mandatory (强制)
| Rule | ESLint rule id | Summary |
|---|---|---|
| Group overloaded signatures | @typescript-eslint/adjacent-overload-signatures | All overloads of the same function/method must be adjacent |
as Type assertions only | @typescript-eslint/consistent-type-assertions | No <Type>x; no assertion on object literals except any |
| No tslint comments | @typescript-eslint/ban-tslint-comment | Remove // tslint:... directives (deprecated tool) |
| Consistent member delimiter | @typescript-eslint/member-delimiter-style | Use ; to separate interface/type members |
| No confusing void type | @typescript-eslint/no-invalid-void-type | void only valid as return type or generic param, not unioned with other types |
No namespace for runtime code | @typescript-eslint/no-namespace | Only allowed inside declare blocks |
| No non-null assertion after optional chaining | @typescript-eslint/no-non-null-asserted-optional-chain | foo?.bar! is a type-safety bug |
No module keyword | @typescript-eslint/prefer-namespace-keyword | Use namespace, except declare module |
| Single quotes | @typescript-eslint/quotes | String literals use '...' |
Matching + operand types | @typescript-eslint/restrict-plus-operands | Both numeric or both string, no mixing |
| No triple-slash reference | @typescript-eslint/triple-slash-reference | Only allowed in .d.ts files |
| Type annotation spacing | @typescript-eslint/type-annotation-spacing | No space before :, one space after; spaces around => |
| Typed interface/type members | @typescript-eslint/typedef | Every member must declare its type |
Recommended (推荐)
| Rule | ESLint rule id | Summary |
|---|---|---|
| Array type style | @typescript-eslint/array-type | T[] for primitives, Array<T> for complex types |
| Explain ts-comment directives | @typescript-eslint/ban-ts-comment | @ts-ignore/@ts-expect-error needs a description |
| Readonly over literal getter | @typescript-eslint/class-literal-property-style | Use readonly field instead of getter returning a literal |
Prefer interface over type | @typescript-eslint/consistent-type-definitions | For object shapes, prefer interface |
| Explicit member accessibility | @typescript-eslint/explicit-member-accessibility | Mark private/protected explicitly; public can be omitted |
| Member ordering | @typescript-eslint/member-ordering | static→instance, field→ctor→method, public→protected→private |
| Method signature as property | @typescript-eslint/method-signature-style | func: (arg: T) => R instead of func(arg: T): R |
| No confusing non-null assertion | @typescript-eslint/no-confusing-non-null-assertion | Avoid ! right before ==/=== |
| No empty interfaces | @typescript-eslint/no-empty-interface | Remove or merge empty/pass-through interfaces |
| No inferrable types | @typescript-eslint/no-inferrable-types | Skip type annotation when default value makes it obvious |
ES2015 import over require | @typescript-eslint/no-require-imports | Use import syntax |
No this alias | @typescript-eslint/no-this-alias | Use arrow functions instead of const self = this |
Prefer as const | @typescript-eslint/prefer-as-const | When value equals its literal type |
| Prefer union param over overloads | @typescript-eslint/unified-signatures | Combine overloads into one signature with union types when only the param type differs |
Examples17 / 20
Example 1 — Type assertion: Input:
TypeScriptconst x = { name: 'a' } as T; const y = <string>someValue;
Output:
TypeScriptconst x: T = { name: 'a' }; // object literal: declare type directly const y = someValue as string; // use `as`, not angle brackets
Example 2 — Array type: Input:
TypeScriptconst list: Array<string> = ['a', 'b']; const objs: { id: string }[] = [];
Output:
TypeScriptconst list: string[] = ['a', 'b']; // simple type -> T[] const objs: Array<{ id: string }> = []; // complex type -> Array<T>
Example 3 — Member ordering & accessibility: Input:
TypeScriptclass Foo { bar = 'bar'; constructor() {} static foo = 'foo'; getBar() {} }
Output:
TypeScriptclass Foo { public static foo = 'foo'; protected bar = 'bar'; public constructor() {} public getBar() {} }
Recommendation▾
Consider trimming the rule reference tables slightly or linking to external docs, since they add length without much unique guidance beyond ESLint rule names already implying behavior.
Best Practices
- Apply the JavaScript coding spec first; this document only adds TS-specific rules on top.
- Prefer
interfacefor object/record shapes because it supportsextends/implementsand gives clearer error messages; usetypefor unions, intersections, tuples, and mapped types. - When suppressing TS errors with directive comments, always explain why — treat it as a TODO marker, not a silence switch.
- Favor ES module syntax and native language features (
as const, optional chaining) over legacy patterns (require,module,self = this). - Use
eslint-config-ali/typescript(or its sub-paths) to enforce these rules automatically rather than manual review alone.
Common Pitfalls
- Using
<Type>valuesyntax — conflicts with JSX and is disallowed; always usevalue as Type. - Casting object literals with
aswhen they should be typed directly (const x: T = {...}instead ofconst x = {...} as T). - Mixing
namespace/moduleinto regular application code instead of ES modules — only valid in ambientdeclarecontexts. - Leaving
// @ts-ignorewithout any explanation — hides real bugs. - Declaring redundant types like
const foo: number = 1when inference already resolves it. - Splitting overloaded function signatures apart in the file instead of grouping them together.
- Using
foo?.bar!— the non-null assertion after optional chaining defeats the safety of?.and is almost always a bug.