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
//...