Передача типов в TypeScript в под функции
-
Попробуем разобрать такую задачу, у нас есть большой конфиг типов который мы передаем в одну функцию, а эта функция передает часть данных в другую функцию. Но как же поступить с типами что бы не писать одно и тоже по нескольку раз.
У нас есть файл типов:
// Общий конфиг type Config = { api: string; text: string; url: string; };И есть главная функция:
function main(config: Config) { const { api, text, url } = config; // Здесь нужно передать ТОЛЬКО часть в другую функцию otherFunction(config); }А функции
otherFunctionтребуется толькоtext: string;.
Да возможно вы скажете, а зачем так вообще заморачиваться если я могу в самый функции при аргумента это все делать. Говно вопрос если мы передаем 1, 2 аргумента, а если там целая тележка? Едем дальше
Решение #1
У TypeScript есть интересная утилита Pick<T, K>, чтобы выбрать подмножество полей из типа.
Вот как это будет выглядеть на практике:type otherType= Pick<Config, 'text'>; function otherFunction(config: otherType) { console.log(config.text); } function main(config: Config) { otherFunction(config); // ✅ TypeScript сам поймёт, что config содержит нужные поля }На заметку - Pick это типобезопасно, не создаёт новых объектов, и не требует ручного копирования.
Решение #2
Если мы не можем менять тип ёotherFunctionё, но можем передавать только нужные поля просто передаем объект с нужными ключами:
function otherFunction({ text }: { text: string; }) { // ... } function main(config: Config) { otherFunction(config); // ✅ тоже сработает! (config совместим структурно) // ИЛИ явно: otherFunction({ text: config.text, }); }TypeScript использует структурную типизацию, поэтому если объект содержит нужные поля он подходит.
Да, такое решение тоже имеет месту быть, но первый вариант все же будет лаконичнее.
Решение #3
Иногда полезно, а иногда и нужно создать новый объект, чтобы передать только необходимое (например, для безопасности или логирования):
function main(config: Config) { const otherConfig = { text: config.text, }; otherFunction(otherConfig); }Тип
otherConfigбудет выведен как{ text: string }- и это совместимо сPick<Config, 'text'>.
Главное правило: не дублируй типы лучше используй утилиты TypeScript или другие варианты.
Gереиспользование наше все! Но наверное новички и вообще уже не помнят про принципы ООП. -
а что думаешь про наследование типов? Или шляпа?
-
@Aladdin а я кстати не пробовал, надо протестить.
Опять же наследование принцип - ООП)))
Можно вообще пора вернуться к классам ? -
Так, я тут осознал, что ты не дораскрыл тему, потому что подмножество типов можно получить не только с помошью
Pick, но и черезOmit, первый удобен, когда тебе надо меньшую часть свойств взять в новый тип, а Omit когда большуюПример:
// Исходный тип type User = { id: number; name: string; email: string; password: string; age: number; role: string; }; // ✅ PICK - "возьми ЭТИ поля" type PickExample = Pick<User, 'id' | 'name' | 'email'>; /* Результат: { id: number; name: string; email: string; } Только указанные поля! */ // ✅ OMIT - "все КРОМЕ этих" type OmitExample = Omit<User, 'password' | 'age'>; /* Результат: { id: number; name: string; email: string; role: string; } Все поля, кроме указанных! */ -
Так, я тут осознал, что ты не дораскрыл тему, потому что подмножество типов можно получить не только с помошью
Pick, но и черезOmit, первый удобен, когда тебе надо меньшую часть свойств взять в новый тип, а Omit когда большуюПример:
// Исходный тип type User = { id: number; name: string; email: string; password: string; age: number; role: string; }; // ✅ PICK - "возьми ЭТИ поля" type PickExample = Pick<User, 'id' | 'name' | 'email'>; /* Результат: { id: number; name: string; email: string; } Только указанные поля! */ // ✅ OMIT - "все КРОМЕ этих" type OmitExample = Omit<User, 'password' | 'age'>; /* Результат: { id: number; name: string; email: string; role: string; } Все поля, кроме указанных! */@Aladdin Ого, вот это кстати пипец какая полезная штука, как говорится - thank u very much!
© 2024 - 2025 ExLends, Inc. Все права защищены.