Показать сообщение отдельно
  #13 (permalink)  
Старый 03.12.2021, 14:02
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,518

voraa, я это себе как-то так представляю(чисто черновой набросок):
function create ({tag, options, children, parent}) {
  console.log({tag, options, children, parent})
}


function isType(arg, types) {
  if(Array.isArray(types))
    return types.some(type => isType(arg, type));
  if(typeof types === 'function')
    return types(arg);
  return arg === types;
}
function findArgs(args, list) {
  let maxArgsMatchLength = -1;
  let maxArgsMatchNames;
  list.forEach(({
    sublist,
    sublist: { length },
    names
  }) => {
    if(length <=  maxArgsMatchLength) return; // ничего не делаем если уже нашли больше аргументов
    for(let i = length; i--;) {
      if(!isType(args[i], sublist[i])) 
        return false;
    }
    maxArgsMatchLength = length;
    maxArgsMatchNames = names;
  });

  if(maxArgsMatchLength === -1)
    throw new Error('invalid arguments');

  return Object.fromEntries(
    maxArgsMatchNames
    .slice(0, maxArgsMatchLength)
    .map((key, i) => [key, args[i]])
  )
}

function withAttrs(func, list) {
  const bigList = list.flatMap(obj => {
    const sublist = [];
    const entries = Object.entries(obj);
    const current = [];
    const names = [];

    for(let arg in obj) {
      const type = obj[arg];
      if(arg.endsWith('?')) {
        arg = arg.slice(0, -1);
        sublist.push(current.slice());
      }
      names.push(arg);
      current.push(type)
    }
    sublist.push(current);

    return sublist.map(arr => ({ sublist: arr, names }));
  })


  return function(...args) {
    return func.call(this, findArgs(args, bigList)); 
  }
}

isNode = () => true;

createWithArgs = withAttrs(create, [
  {tag: isString, options: isPlainObject, 'children?': [isNode, isArray, isString], 'parent?': isElement},
  {tag: isString, 'children?': [isNode, isArray, isString, null], 'parent?': isElement},
]);

createWithArgs('1', {a: 3}, [])


Все isX функции из lodash, но естественно возможно использование своих.
+Обязательно должно бы кэширование: чтоб одна функция проверки типа вызывалась для одного конкретного аргумента только один раз.
+Разделить проверку списка аргументов не всех сразу, а по порядку.
+Добавить поддержку spread.
+Типизировать для typescript(это будет ад, если вообще возможно).
...
=)
__________________
29375, 35

Последний раз редактировалось Aetae, 03.12.2021 в 14:47.
Ответить с цитированием