interface IStorageConfig<T, K> {
oftype: new () => IStorage<T, K>;
}
const matchStorageConfig: IStorageConfig<Match, number> = {
oftype: MatchStorage
}
const s = new matchStorageConfig.oftype();
{[K in keyof T]: ...}
- это специальный особый паттерн, где ты итерируешься по ключам "локального типа" внутри генерика (аналог локальной переменной внутри функции). Важен тот факт, что тип именно локальный - либо параметр генерика, либо что-то, извлеченное с помощью infer.type MappedGenericStringType1<T, Keys extends keyof T = keyof T> = {
[K in Keys]: any;
};
// или так
type MappedGenericStringType2<T> = keyof T extends infer Keys extends keyof T ? {
[K in Keys]: any;
} : never;
const array: Array<IQuest | IPost | IAlbum | IContest>;
array.forEach((item) => {
// сейчас item - IQuest | IPost | IAlbum | IContest
if (item.namespace === 'quest') {
// здесь item - IQuest, typescript сам об этом догадался по условию
} else if (item.namespace === 'post') {
// здесь item - IPost
} // и т.д.
})
type GetStrKeys<T> = keyof {[K in keyof T as T[K] extends string ? K : never]: T[K]};
type SortKeys = GetStrKeys<IPost>;
.......
const [selectedSort, setSelectedSort] = useState<SortKeys>(); // SortKeys | undefined;
const sortedPosts = useMemo(() => selectedSort
? [...posts].sort((a, b) => a[selectedSort].localeCompare(b[selectedSort]))
: posts,
[posts, selectedSort]
);
.....
<PostList posts={sortedPosts} sortPosts={setSelectedSort} remove={deletePost} />
type CompanyInfoSectionProps = {
title: string;
to: string;
items: string[];
[key: `_${string}`]: string | boolean;
};
["useVerificationToken", "getUserByEmail"].filter((method) => !adapter[method])
(["useVerificationToken", "getUserByEmail"] as const).filter((method) => !adapter[method])
type Schemas<P extends keyof paths> = paths[P]['post'] extends {requestBody: infer R} ? R : never;
export function getDocuments<T>(slug: ''): Promise<T[]>;
export function getDocuments<T>(slug: string): Promise<T>;
export function getDocuments<T>(): Promise<T[]>;
export function getDocuments(slug = ''): Promise<unknown> {
const endpoint = `/documents/${slug}`
return getPosts(endpoint);
}
export const setFrame = (titlle: string): setFrameActionType => ({ type: 'SETFRAME', payload: { titlle } });
const columns = [
{
key: "name",
label: "NAME",
},
{
key: "role",
label: "ROLE",
},
{
key: "status",
label: "STATUS",
},
] as const;
type ColumnsType = typeof columns;
const rows: Array<Record<ColumnsType[number]['key'], string> & {key: string}> = [
{
key: "1",
name: "Tony Reichert",
role: "CEO",
status: "Active",
},
{
key: "2",
name: "Zoey Lang",
role: "Technical Lead",
status: "Paused",
},
];
type Reserve = {
(from: Date, to: Date, destination: string): Ticket;
(from: Date, destination: string): Ticket
};
const reserve: Reserve = (from: Date, ...args: [toOrDest: Date, destination: string] | [destination: string]): Ticket => {
const isOne = args.length === 1;
return {
type: isOne ? "one-way" : "two-way",
from,
destination: isOne ? args[0] : args[1],
...(isOne ? {} : {to: args[0]})
};
};
Reserve
. Но тогда при наведении мыши на reserve
будет не совсем понятная подсказка (хотя автокомплит вполне корректный).