← Назад к вопросам
Как указать в методе что должен прийти какой-либо тип?
1.0 Junior🔥 251 комментариев
#Node.js и JavaScript#TypeScript
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как указать тип параметра в методе
В Node.js есть несколько способов указывать типы параметров в методах. Выбор зависит от стека и требований проекта.
1. TypeScript (рекомендуемый подход)
Типичная современная практика в production-среде.
Базовые типы
// Примитивные типы
function greet(name: string, age: number, active: boolean): void {
console.log(`${name} is ${age} years old`);
}
greet('Alice', 30, true); // ✅ OK
greet('Bob', '25', true); // ❌ Error: Argument of type 'string' is not assignable to parameter of type 'number'
Сложные типы
// Интерфейсы
interface User {
id: number;
name: string;
email?: string; // Опциональное поле
}
function createUser(user: User): User {
return { ...user, id: Math.random() };
}
// Типы
type Status = 'active' | 'inactive' | 'pending';
function updateUserStatus(userId: number, status: Status): void {
console.log(`User ${userId} status: ${status}`);
}
updateUserStatus(1, 'active'); // ✅ OK
updateUserStatus(1, 'unknown'); // ❌ Error: not assignable
Классы с типами
class UserService {
createUser(user: User): Promise<User> {
return Promise.resolve(user);
}
findById(id: number): User | null {
// Может вернуть User или null
return null;
}
getUsers(): User[] {
return [];
}
}
Обобщённые типы (Generics)
// Универсальная функция
function echo<T>(value: T): T {
return value;
}
echo<string>('hello'); // Type: string
echo<number>(42); // Type: number
// Обобщённый класс
class Repository<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
getAll(): T[] {
return this.items;
}
}
const userRepo = new Repository<User>();
userRepo.add({ id: 1, name: 'Alice' }); // ✅ OK
userRepo.add('not a user'); // ❌ Error
Union Types
function process(value: string | number | boolean): void {
if (typeof value === 'string') {
console.log(value.toUpperCase());
} else if (typeof value === 'number') {
console.log(value * 2);
}
}
process('hello'); // ✅ OK
process(42); // ✅ OK
process(true); // ✅ OK
process([]); // ❌ Error
2. JSDoc в JavaScript (для legacy проектов)
Если проект всё ещё на чистом JavaScript, но хочешь типизацию.
/**
* Создаёт пользователя
* @param {Object} user - Объект пользователя
* @param {number} user.id - ID пользователя
* @param {string} user.name - Имя
* @param {string} [user.email] - Email (опциональный)
* @returns {Promise<Object>} Созданный пользователь
*/
async function createUser(user) {
return await db.users.insert(user);
}
/**
* Валидирует возраст
* @param {number} age - Возраст пользователя
* @returns {boolean} Валидный ли возраст
*/
function isValidAge(age) {
return age >= 18 && age <= 120;
}
// IDE покажет типи, но runtime проверки нет
3. Runtime проверка типов (валидация)
Для Production важна не только типизация, но и runtime валидация.
С использованием Zod
import { z } from 'zod';
const UserSchema = z.object({
id: z.number(),
name: z.string().min(2).max(100),
email: z.string().email(),
age: z.number().min(0).max(150).optional(),
});
type User = z.infer<typeof UserSchema>; // Автоматически из schema
function createUser(data: unknown): User {
// Валидирует в runtime
return UserSchema.parse(data);
// Выбросит ошибку, если data не соответствует schema
}
createUser({ name: 'Alice', email: 'test@example.com' }); // ❌ id обязателен
createUser({ id: 1, name: 'Alice', email: 'test@example.com' }); // ✅ OK
С использованием Joi (для Express)
import Joi from 'joi';
const userSchema = Joi.object({
id: Joi.number().required(),
name: Joi.string().min(2).max(100).required(),
email: Joi.string().email().required(),
});
app.post('/users', (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details });
}
// value содержит валидные данные
const user = createUser(value);
res.json(user);
});
4. Class Validator (для NestJS/TypeORM)
import { IsString, IsEmail, IsNumber, IsOptional } from 'class-validator';
export class CreateUserDto {
@IsNumber()
id: number;
@IsString()
name: string;
@IsEmail()
email: string;
@IsOptional()
@IsNumber()
age?: number;
}
// В контроллере
@Post('/users')
async create(@Body() createUserDto: CreateUserDto) {
// Автоматически валидируется
return this.userService.create(createUserDto);
}
5. Strict Mode в TypeScript
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitAny": true,
"noImplicitThis": true
}
}
Эти настройки принуждают тебя быть явным с типами:
// Без strict mode (опасно)
function process(value) { // ❌ Неявный any
return value.toUpperCase(); // Может упасть в runtime
}
// Со strict mode (безопасно)
function process(value: string): string {
return value.toUpperCase();
}
Практический пример: полный сценарий
// schema.ts
import { z } from 'zod';
export const UserSchema = z.object({
id: z.number(),
name: z.string().min(2),
email: z.string().email(),
});
export type User = z.infer<typeof UserSchema>;
// service.ts
class UserService {
async createUser(data: unknown): Promise<User> {
const validated = UserSchema.parse(data); // Runtime валидация
// Сохраняем в БД
return validated;
}
async getUserById(id: number): Promise<User | null> {
// Возвращает User или null (явная типизация)
return null;
}
}
// controller.ts
app.post('/users', async (req, res) => {
try {
const user = await userService.createUser(req.body);
res.json(user); // user: User (TypeScript знает структуру)
} catch (error) {
res.status(400).json({ error: 'Invalid user data' });
}
});
Рекомендации
- Используй TypeScript для production-кода
- Strict mode: true в tsconfig.json
- Валидирование в runtime (Zod, Joi, class-validator)
- Типизируй всё явно — не полагайся на type inference
- Избегай
any— используйunknown+ type guard, если нужно
// ❌ Плохо
function process(value: any): any {
return value.something();
}
// ✅ Хорошо
function process(value: unknown): string {
if (typeof value === 'object' && value !== null && 'method' in value) {
return value.method();
}
throw new Error('Invalid input');
}
Типизация в TypeScript — это не просто документация, это страховка для production-кода. Правильно типизированный код == меньше багов в production.