Как правильно проставить возвращаемый тип функции?

Ссылка скопирована
1 ответ

Всем привет, на ts часто пишу но в основном использую базовые штуки, до сложного пока как то не добирался по причине ненадобности но сейчас не могу понять как правильно описать возвращаемый тип для функции, на ум приходят всякие условия (как в примере ниже) но учитывая что такое я еще не писал то хз как это правильно делается, заранее благодарю за помощь, пример тестовый так что сильно не ругайте

// Enum нужен потому что я хочу потом где-то использовать эти ключи const enum TestKeys {   A = 'a',   B = 'b',   C = 'c', }  type BaseTest = { label: string, value: any }  interface Type extends Record<TestKeys, BaseTest> {   [TestKeys.A]: { label: string, value: number },   [TestKeys.B]: { label: string, value: string },   [TestKeys.C]: { label: string, value: boolean } }  const test: Type = {   [TestKeys.A]: { label: '', value: 12 },   [TestKeys.B]: { label: '', value: 'test' },   [TestKeys.C]: { label: '', value: true } }  // Partial так как это пример объекта // Но по ходу рантайма он может менять кол-во объектов внутри function testFn<T extends Partial<Type>, K extends TestKeys>(   obj: T, key: K ): T[K] extends unknown ? undefined : T[K]['value'] {   return key in obj ? obj[key]!.value : undefined }  // Return type должен быть string | undefined const result = testFn(test, TestKeys.B)

// Enum нужен потому что я хочу потом где-то использовать эти ключи const enum TestKeys { A = 'a', B = 'b', C = 'c', } type BaseTest = { label: string, value: any } interface Type extends Record<TestKeys, BaseTest> { [TestKeys.A]: { label: string, value: number }, [TestKeys.B]: { label: string, value: string }, [TestKeys.C]: { label: string, value: boolean } } const test: Type = { [TestKeys.A]: { label: '', value: 12 }, [TestKeys.B]: { label: '', value: 'test' }, [TestKeys.C]: { label: '', value: true } } // Partial так как это пример объекта // Но по ходу рантайма он может менять кол-во объектов внутри function testFn<T extends Partial<Type>, K extends TestKeys>( obj: T, key: K ): T[K] extends unknown ? undefined : T[K]['value'] { return key in obj ? obj[key]!.value : undefined } // Return type должен быть string | undefined const result = testFn(test, TestKeys.B)

Дополнительно:

key in obj ? obj[key]!.value

А теперь представим, что у нас там свойство со значением андефайнд.

  • WbICHA, это вариант для примера, в проекте 100% не будет undefined так как там где его можно менять при сохранении идет проверка структуры через Joi
  • Александр Антонов, тогда зачем партиал?
  • WbICHA, так самих ключей может и не быть в объекте, так как позволено убирать или добавлять элементы в основной обьект,
    const defObj = {   a: { label: string, value: number },   b: { label: string, value: string },   c: { label: string, value: boolean } }

    const defObj = { a: { label: string, value: number }, b: { label: string, value: string }, c: { label: string, value: boolean } }

    Потом юзер захотел убрать свойство "a" так как это некоторая experemental настройка в админке, а сам набор доступных ключей в типах нужен для удобства в коде, что бы не писать обобщенный тип

    type Generic =    | { label: string, value: number }   | { label: string, value: string}   | { label: string, value: boolean}  type Test = Record<string, Generic>

    type Generic = | { label: string, value: number } | { label: string, value: string} | { label: string, value: boolean} type Test = Record<string, Generic>

    Да и так тогда не получиться в коде правильно типизировать значение когда функцией (которая в вопросе) буду забирать нужную exp настройку

  • Александр Антонов, а зачем вообще эта функция нужна? Не проще напрямую к св-ву обращаться?
    obj[key]?.value
  • WbICHA, там всякие доп проверки
  • function testFn<T extends Type, K extends TestKeys>(   obj: Partial<T>, key: K ): T[K]['value'] | undefined {   return key in obj ? obj[key]!.value : undefined }

    function testFn<T extends Type, K extends TestKeys>( obj: Partial<T>, key: K ): T[K]['value'] | undefined { return key in obj ? obj[key]!.value : undefined }

    • Тьфу блин, вот я протупил конечно с тем что от Partial расширялся, спасибо
    • Александр Антонов, можно в генерике обойтись одним параметром
      function testFn<K extends TestKeys>(   obj: Partial<Type>, key: K ): Type[K]['value'] | undefined {   return key in obj ? obj[key]!.value : undefined }

      function testFn<K extends TestKeys>( obj: Partial<Type>, key: K ): Type[K]['value'] | undefined { return key in obj ? obj[key]!.value : undefined }

    • Alexandroppolus, Согласен
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Юрий Linux Ответ

    Для правильного указания возвращаемого типа функции в PHP, необходимо использовать синтаксис PHP 7. В PHP 7 была добавлена поддержка объявления возвращаемых типов для скалярных типов данных (int, string, float, bool) и объектов.

    Для того чтобы указать тип возвращаемого значения функции, необходимо после открывающей скобки указать двоеточие и тип данных, который функция будет возвращать. Например:

    function sum(int $a, int $b): int {
        return $a + $b;
    }

    function sum(int $a, int $b): int { return $a + $b; }

    В данном примере функция sum принимает два аргумента типа int и возвращает результат их сложения, который также имеет тип int.

    Если функция не должна возвращать какое-либо значение, можно указать тип void:

    function logMessage(string $message): void {
        echo $message;
    }

    function logMessage(string $message): void { echo $message; }

    Также можно указать возвращаемый тип как объект определенного класса:

    class User {
        public string $name;
     
        function getName(): string {
            return $this->name;
        }
    }
     
    function createUser(string $name): User {
        $user = new User();
        $user->name = $name;
     
        return $user;
    }

    class User { public string $name; function getName(): string { return $this->name; } } function createUser(string $name): User { $user = new User(); $user->name = $name; return $user; }

    Важно помнить, что указание возвращаемого типа не является обязательным, но может быть полезным для документирования кода и обеспечения его надежности. При этом PHP не выполняет строгую типизацию, поэтому необходимо учитывать возможные ошибки типов во время выполнения программы.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно