Ограничить универсальный тип литеральным типом

У меня двоякий вопрос:

  1. Я хотел бы знать, есть ли в TypeScript способ ограничить универсальный тип каким-либо буквальным типом. Я имею в виду что-то вроде function foo<T is a string literal>(...). Ближе всего к такому поведению я подошел function foo<T extends string>, но это позволяет объединять строковые литералы и сам тип "строка" в качестве значений для T.
  2. Если это невозможно в TypeScript 2.1, имеет ли смысл с точки зрения дизайна реализовать такую ​​функцию?

Мой вариант использования - определить каррированную функцию prop следующим образом:

function prop<K extends string, U>(name: K): <T extends { [P in K]: U  }>(obj: T) => T[K] {
    return (obj) => obj[name];
}

prop<'name', number>("name")({
    name: 3
})

Этот пример работает так, как ожидалось, если K является строковым литералом, но проверка типов функции разбивает K string.

Я знаю, что это немного надумано; пожалуйста, не моя цель - не решить практическую проблему (хотя это могло бы быть), а скорее поэкспериментировать с системой типов TypeScript.

Спасибо!


person Aegis    schedule 10.12.2016    source источник
comment
Есть ли цель создать функцию, которая может извлекать произвольные свойства из объекта безопасным способом?   -  person Asad Saeeduddin    schedule 12.12.2016


Ответы (1)


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

Вот пример того, что, как я думаю, вы пытаетесь достичь:

function propGetter<O>(o: O): <K extends keyof O>(key: K) => O[K] {
    return k => o[k];
}

let prop = propGetter({
    id: 10,
    firstName: "Dununuh Hunudunuh"
});

let id = prop("id");               // number
let firstName = prop("firstName"); // string
let foo = prop("foo");             // Type error
person Asad Saeeduddin    schedule 12.12.2016
comment
Спасибо за ответ! Однако это легкий выход. Я специально пытался сделать обратное: ограничить объект на основе имени свойства. Вариант использования, о котором я думал, будет с функциональными линзами. - person Aegis; 12.12.2016