typescript-advanced — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited typescript-advanced (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Any task involving advanced TypeScript type system features: generics design, conditional types, discriminated unions, mapped types, template literal types, branded types, variance annotations, or complex type inference patterns.
the type system make impossible?"
tsconfig.json for strict: true. If not enabled, flag itas a prerequisite for advanced type patterns to work correctly.
require more careful design than internal utility types).
#### Generics
<T extends BaseType> not bare <T>.<T extends Record<string, unknown> = Record<string, unknown>>. // Good: T is inferred from the argument
function wrap<T>(value: T): Wrapper<T>
// Bad: T cannot be inferred, caller must specify
function wrap<T>(): Wrapper<T> type Config<TInput, TOutput, TError> = { ... }
function process<C extends Config<any, any, any>>(config: C): ...#### Conditional Types
infer keyword to extract types from structures: type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type ReturnOf<T> = T extends (...args: any[]) => infer R ? R : never;T extends U ? X : Y distributes over unionswhen T is a naked type parameter. Wrap in [T] extends [U] to prevent distribution.
// Instead of deeply nested conditionals
type Step1<T> = T extends Array<infer U> ? U : T;
type Step2<T> = Step1<T> extends object ? keyof Step1<T> : never;#### Discriminated Unions
type or kind): type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number }
| { kind: "triangle"; base: number; height: number };never checks: function assertNever(x: never): never {
throw new Error(`Unexpected: ${JSON.stringify(x)}`);
}
function area(shape: Shape): number {
switch (shape.kind) {
case "circle": return Math.PI * shape.radius ** 2;
case "rectangle": return shape.width * shape.height;
case "triangle": return 0.5 * shape.base * shape.height;
default: return assertNever(shape);
}
}switch/if that is missing the new case. This is the primary value.
#### Mapped Types
as) for transforming keys: type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};readonly, ?, -readonly, -?) deliberately: type Mutable<T> = { -readonly [K in keyof T]: T[K] };
type Required<T> = { [K in keyof T]-?: T[K] };as with never: type OnlyStrings<T> = {
[K in keyof T as T[K] extends string ? K : never]: T[K];
};#### Template Literal Types
type EventName<T extends string> = `on${Capitalize<T>}`;
type Route = `/${string}` | `/${string}/${string}`; type CSSProperties = {
[K in keyof CSSStyleDeclaration as K extends string
? `--${K}` | K
: never]: string;
};Uppercase, Lowercase, Capitalize, Uncapitalize.#### Branded / Opaque Types
declare const brand: unique symbol;
type Brand<T, B> = T & { readonly [brand]: B };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
// Now these are incompatible even though both are strings
function getUser(id: UserId): User { ... }
const orderId = "abc" as OrderId;
getUser(orderId); // Compile error! function createUserId(raw: string): UserId {
if (!raw.startsWith("usr_")) throw new Error("Invalid UserId format");
return raw as UserId;
}#### Variance Annotations
in (contravariant) and out (covariant) on generic type parametersfor explicit variance when the compiler cannot infer it:
type Consumer<in T> = (value: T) => void;
type Producer<out T> = () => T;
type Transformer<in I, out O> = (input: I) => O;#### The satisfies Operator
satisfies to validate a value matches a type without widening: const palette = {
red: [255, 0, 0],
green: "#00ff00",
} satisfies Record<string, string | number[]>;
// palette.red is still number[] (not string | number[])satisfies over as const + type annotation when you need bothtype checking AND narrow inference.
#### Type Guards and Narrowing
is return type for custom type guards: function isCircle(shape: Shape): shape is { kind: "circle"; radius: number } {
return shape.kind === "circle";
}asserts for assertion functions that throw: function assertDefined<T>(val: T | undefined): asserts val is T {
if (val === undefined) throw new Error("Expected defined value");
}in operator narrowing for object type checks over typeof for complex objects.npx tsc --noEmit passes with zero errors.// @ts-expect-error comment proving thetype correctly rejects invalid usage.
types can crash the language server).
Before marking a task done when this skill was active:
<T> without extends).never fallback.any types introduced (use unknown and narrow).@ts-expect-error negative tests prove the types reject invalid input.tsc --noEmit passes cleanly.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.