@Kvinc

Как типизировать функцию, которая возвращает данные по ключам объекта?

Есть функция на JS:
function getPropertyOfObject(obj) {
  return function (keyOne, keyTwo = 'defaultKey') {
    if (obj && obj[keyOne] && obj[keyOne][keyTwo]) {
      return obj[keyOne][keyTwo]
    }
  return null
  }
}


Которая используется следующим образом

const myObject = {
  otherKey: { // рандомный ключ
    moreKey: 123, // всегда тип number
    defaultKey: 'other data' // разные типы данных, но заранее описан тот тип, что будет конкретно в этом объекте
  },
  otherMoreKey: { // рандомный ключ
    moreKey: 123, // всегда тип number
    defaultKey: 'other data' // разные типы данных, но заранее описан тот тип, что будет конкретно в этом объекте
  }
}

const getProp = getPropertyOfObject(myObject)

const listMoreKey = getProp('otherKey', 'moreKey') 
// так, что бы listKey понимал, что в нем будет тип typeof myObject.otherKey.moreKey | null

const listDefaultKey = getProp('otherMoreKey')
// так, что бы listKey понимал, что в нем будет тип typeof myObject.otherKey.defaultKey | null


Как типизировать эту функцию БЕЗ ИСПОЛЬЗОВАНИЯ значения по умолчанию keyTwo = 'defaultKey'
я точно знаю и это работает, вопрос как сделать именно с ним.
  • Вопрос задан
  • 213 просмотров
Решения вопроса 2
Aetae
@Aetae Куратор тега JavaScript
Тлен
TS очень не любит работать с произвольными объектами, так что совсем без any получится огромное убожество имеющее одну цель - ублажить TS. Оно того не стоит.

С any же всё просто, но надо быть аккуратным.
function getPropertyOfObject<T extends Record<PropertyKey, any>>(obj: T) {
    const defaultKey = 'defaultKey';
    function getProp<K extends keyof T>(keyOne: K): typeof defaultKey extends keyof T[K] ? T[K][typeof defaultKey] : void;
    function getProp<K extends keyof T, K2 extends keyof T[K]>(keyOne: K, keyTwo: K2): T[K][K2];
    function getProp(keyOne: PropertyKey, keyTwo?: PropertyKey) {
        return obj?.[keyOne]?.[keyTwo ?? defaultKey];
    }
    return getProp;
}
Ответ написан
Комментировать
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
const DEFAULT_KEY = 'defaultKey';
type DEFAULT_KEY = typeof DEFAULT_KEY;

type BaseObject = Record<PropertyKey, Record<PropertyKey, unknown>>;

type PropertyOfObject<T extends BaseObject> = {
    <K extends keyof T>(key: K): DEFAULT_KEY extends keyof T[K] ? T[K][DEFAULT_KEY] : null;
    <K0 extends keyof T, K1 extends keyof T[K0]>(key0: K0, key1: K1): T[K0][K1];
};

function getPropertyOfObject<T extends BaseObject>(obj: T): PropertyOfObject<T> {
  type K0 = keyof T;
  type K1 = DEFAULT_KEY | keyof T[K0];
  return ((keyOne: K0, keyTwo: K1 = DEFAULT_KEY) =>
    obj[keyOne]?.[keyTwo] ?? null
  ) as PropertyOfObject<T>;
}

https://www.typescriptlang.org/play?#code/MYewdgzg...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы