← Назад к вопросам

Как получить тип возвращаемого значения из функции?

1.7 Middle🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Проблема и контекст

В TypeScript часто нужно извлечь тип возвращаемого значения функции без явного указания. Это полезно для динамических типов, дженериков и переиспользования типов.

Решение 1: Использование ReturnType<typeof>

function getUserById(id: number) {
  return {
    id,
    name: 'John',
    email: 'john@example.com'
  };
}

type UserReturn = ReturnType<typeof getUserById>;

const user: UserReturn = getUserById(1);
console.log(user.name);

Решение 2: Для async функций

async function fetchUser(id: number) {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}

// Правильно - используй Awaited
type UserData = Awaited<ReturnType<typeof fetchUser>>;

// Или явно типизируй
interface User {
  id: number;
  name: string;
}

async function fetchUserTyped(id: number): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}

type UserCorrect = Awaited<ReturnType<typeof fetchUserTyped>>;

Решение 3: С использованием как const

const createUser = () => ({
  id: 1,
  name: 'Alice',
  age: 30
} as const);

type User = ReturnType<typeof createUser>;

Решение 4: Для обобщённых функций (дженериков)

function processData<T>(data: T): { data: T; timestamp: number } {
  return {
    data,
    timestamp: Date.now()
  };
}

type ProcessResult<T> = ReturnType<typeof processData<T>>;

type StringResult = ProcessResult<string>;
type NumberResult = ProcessResult<number>;

Решение 5: В React компонентах и хуках

function useUser(id: number) {
  const [user, setUser] = React.useState<User | null>(null);
  const [loading, setLoading] = React.useState(false);

  React.useEffect(() => {
    setLoading(true);
    fetchUser(id).then((data) => {
      setUser(data);
      setLoading(false);
    });
  }, [id]);

  return { user, loading };
}

type UseUserReturn = ReturnType<typeof useUser>;

Решение 6: Для методов класса

class UserService {
  getUser(id: number): { id: number; name: string } {
    return { id, name: 'John' };
  }

  async getUserAsync(id: number): Promise<{ id: number; name: string }> {
    const response = await fetch(`/api/users/${id}`);
    return response.json();
  }
}

type GetUserReturn = ReturnType<UserService['getUser']>;
type GetUserAsyncReturn = Awaited<ReturnType<UserService['getUserAsync']>>;

Сравнение методов

  • ReturnType: для синхронных функций
  • Awaited: для async функций
  • as const: когда нужны literal типы
  • Interface: для переиспользуемых типов

Практический пример в React приложении

// api.ts
export function getUsersApi() {
  return fetch('/api/users').then(r => r.json());
}

// types.ts
type Users = Awaited<ReturnType<typeof getUsersApi>>;

// component.tsx
import { getUsersApi } from '@/api';
import type { Users } from '@/types';

export function UsersComponent() {
  const [users, setUsers] = useState<Users>([]);

  useEffect(() => {
    getUsersApi().then(data => setUsers(data));
  }, []);

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}