2016-04-26 3 views
3

Скажем, у меня есть интерфейс:Поддерживает ли TypScript «типы подмножества»?

interface IUser { 
    email: string; 
    id: number; 
    phone: string; 
}; 

Тогда у меня есть функция, которая ожидает подмножества (или полное совпадение) этого типа. Может быть, он пройдет целый объект, заставив его просто пройти в {email: "[email protected]"}. Я хочу, чтобы контролер типа позволял обоим.

Пример:

function updateUser(user: IUser) { 
    // Update a "subset" of user attributes: 
    $http.put("https://stackoverflow.com/users/update", user); 
} 

Поддерживает ли Машинопись такое поведение еще? Я мог бы найти его очень полезным, особенно с такими парадигмами, как Redux.

Для уточнения, цель:

  1. Избегайте переписывания интерфейса и настройки вручную все атрибуты необязательны.
  2. Избегайте назначения неожиданных атрибутов (например, орфографических ошибок).
  3. Избегайте императивной логики, такой как if заявления, которые лишаются преимуществ проверки типа времени компиляции.

UPDATE: Машинопись объявила о поддержке mapped types, который должен решить эту проблему раз опубликования.

+0

не 'Partial', что вы ищете? –

+0

Их не было, когда я задал вопрос. Я добавил ссылку позже, после того, как они были добавлены в TS. – Rick

ответ

6

Машинопись теперь поддерживает частичные типы.

Правильный способ для создания частичного типа является:

type PartialUser = Partial<IUser>;

1

Вы можете объявить некоторые или все поля в качестве необязательных полей.

interface IUser { 
    email: string; // not optional 
    id?: number; // optional 
    phone?: string; // optional 
}; 
+0

Это близко, но не совсем то, что я хочу. В случае IUser все поля являются обязательными. Просто при определенных обстоятельствах я хотел бы, чтобы это было частичное совпадение. – Rick

+0

требования противоречивы, вы не можете иметь поле необязательное и обязательное в одно и то же время. : P Я предполагаю, что вы могли бы использовать 2 интерфейса, чтобы получить это, хотя .. – toskv

+1

Существует много раз, когда вы хотите, чтобы этот и другие языки (например, Flow) допускали это. Именно для СУШКИ вы хотите разрешить подмножество при определенных обстоятельствах. Рассмотрим базовые обновления модели, где вы назвали параметры, которые должны быть подмножеством атрибутов модели. – Rick

1

Вы можете отделить его в различные интерфейсы:

interface IUser { 
    id: number; 
}; 

interface IUserEmail extends IUser { 
    email: string; 
} 

interface IUserPhone extends IUser { 
    phone: string; 
} 

Иметь свой метод получить базу IUser интерфейс, а затем проверить для полей, которые необходимо:

function doit(user: IUser) { 
    if (user.email) { 

    } else if (user.phone) { 

    } 
} 
1

Если бы я правильно поняли этот вопрос, вам нужно что-то вроде Flow's $Shape

Так, в одном месте, вы можете иметь то, что требует от типа

interface IUser { 
    email: string; 
    id: number; 
    phone: string; 
}; 

Затем, в другом месте вы хотите тип такого же типа, как IUser только со всеми полями теперь необязательно.

interface IUserOptional { 
    email?: string; 
    id?: number; 
    phone?: string; 
}; 

Вы хотите способ автоматической генерации IUserOptional на основе IUser без необходимости выписывать тип снова.

Теперь, я не думаю, что это возможно в TypScript. Вещи могут измениться в 2.0, но я не думаю, что мы даже близки к чему-то подобному в TypScript.

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

Учитывая эту проблему, я могу предложить вам попробовать вместо Flow вместо этого.В потоке вы можете просто сделать $Shape<IUser>, чтобы сгенерировать тип, который вы хотите программно. Конечно, Flow отличается от Typcript многими большими и малыми способами, поэтому имейте это в виду. Поток не компилятор, так что вы не получите такие вещи, как Перечисления и класса реализации interfactes

0

правильное решение с отображенных типов:

updateUser<K extends keyof IUser>(userData: {[P in K]: IUser[P]}) { 
    ... 
} 
Смежные вопросы