Как ограничить ввод функции динамически назначаемыми клавишами объекта в машинописном тексте? - PullRequest
0 голосов
/ 14 июля 2020

в последнее время я пытаюсь создать объект-заполнитель, который я смогу использовать с машинописным текстом. Идея состоит в том, чтобы иметь пустой объект и две функции:

  • одну для добавления нового ключа к объекту-заполнителю с другим объектом в качестве значения (функция 'add')
  • и одну для получить это значение, передав ключ, который уже существует в заполнителе (функция 'get')

Я хотел бы, чтобы машинописный текст запретил вводить ключи, которые уже существуют в заполнителе в функции 'добавить'. Также я хотел бы получать предложения при вводе клавиши в функции «получить». Последнее, чего я хотел бы достичь, - это иметь тип объекта, который возвращается из функции 'get' вместо 'any' или 'object'.

Вот пример кода с некоторыми базовыми c типами :

let placeholder = {}
    
function add(key: string, test: object) {
    placeholder[ key ] = test
}

function get(key: string ) {
    return placeholder[key]
}

add('test1', { val: 1 }) // here 'test1' is ok
add('test1', { val: 2 }) // here 'test1' should rise an error
let t1 = get('') // here 'test1' and should be suggested
t1.val // here t1 should have type { val: number }

До сих пор я пробовал использовать типы generi c с такими вещами, как:

function add( key: Omit< string, keyof typeof placeholder >, test: object ) { ... } // it is casting key to properties of string
function get< Key extends keyof typeof placeholder > ( key: Key ) { ... } // it only works with static keys

1 Ответ

0 голосов
/ 15 июля 2020

Это невозможно. Для этого потребуется изменить тип объекта, но типы - это stati c.

Единственное, что вы могли бы сделать, - это вернуть объект из вашей add функции с измененным типом, а затем продолжить вызывает этот объект.

Пример такого подхода (все еще есть одна проблема с набором текста, которую я игнорирую):

class Placeholder<T>
{
  constructor(private entries: T)
  {
  }
    
  add<K extends string, V>(key: Exclude<K, keyof T>, value: V): Placeholder<T & { [X in K]: V }> {
    const newEntries = { ...this.entries, [key]: value };

    // @ts-ignore
    return new Placeholder(newEntries);
  }

  get(key: keyof T) {
    return this.entries[key];
  }
}

const ph = new Placeholder({})
  .add('test1', { val: 1 }) // here 'test1' is ok
  .add('test1', { val: 2 }) // here 'test1' should rise an error
let t1 = ph.get('test1') // here 'test1' and should be suggested
t1.val // here t1 should have type { val: number }

[Playground Link]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...