TypeScript

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  text-align: center;
}

TypeScript

// -----------------------------------------------------------------------
// Generic type aliases in TypeScript
// This is the direct TypeScript equivalent of the PHPStan feature being
// proposed in https://github.com/phpstan/phpstan-src/pull/5378.
// TypeScript has supported generic `type` aliases since v1.0, so every
// scenario below already works today — PHPStan is catching up.
// -----------------------------------------------------------------------

// -----------------------------------------------------------------------
// Abstract Provider / ConcreteProvider
// Generic alias with a default type argument
// -----------------------------------------------------------------------

type Filter = { skuId?: number; condition?: string };

type ProviderRequest<TFilter extends Record<string, unknown> = Record<string, unknown>> = {
    filters?: TFilter;
    limit?: number;
    offset?: number;
};

abstract class Provider {
    abstract find(request: ProviderRequest<Filter>): void;
}

class ConcreteProvider extends Provider {
    find(request: ProviderRequest<Filter>): void {
        // TypeScript knows request.filters is Filter | undefined
        const skuId: number | undefined = request.filters?.skuId;
        console.log(skuId);
    }
}

// -----------------------------------------------------------------------
// Direct usage in the same class
// -----------------------------------------------------------------------

type AppraisalFilter = { skuId?: number; condition?: string };

type DirectProviderRequest<TFilter extends Record<string, unknown>> = {
    filters?: TFilter;
    limit?: number;
    offset?: number;
};

class DirectUsage {
    find(request: DirectProviderRequest<AppraisalFilter>): void {
        const skuId: number | undefined = request.filters?.skuId; // ✅ not unknown
    }
}

// -----------------------------------------------------------------------
// Two template params
//...