Вот одно решение с использованием IsUnion
, которое, в свою очередь, опирается на UnionToIntersection
:
type UnionToIntersection =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type IsUnion =
[T] extends [UnionToIntersection] ? false : true
type DisjointUnion =
{ [k in T["key"]]: IsUnion> } extends { [k in T["key"]]: false } ? T : never;
Использование объединения с различными значениями key
это нормально:
type Union = DisjointUnion; // Item1 | Item2
Но добавьте элемент с уже существующим ключом, и результирующий тип будет never
:
type Union = DisjointUnion; // never
Или вы можете использовать MessageFilter C #. Он должен работать, пока любой элемент управления / форма из процесса вашего приложения находится в фокусе.
Пример кода:
class KeyboardMessageFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == ((int)Helper.WindowsMessages.WM_KEYDOWN))
{
switch ((int)m.WParam)
{
case (int)Keys.Escape:
// Do Something
return true;
case (int)Keys.Right:
// Do Something
return true;
case (int)Keys.Left:
// Do Something
return true;
}
}
return false;
}
}
А затем просто добавьте новый MessageFilter в ваше приложение:
Application.AddMessageFilter(new KeyboardMessageFilter());
Сообщение Пола ссылается на два ответа, в одном из которых рассказывается, как реализовать ловушку, и еще один советует вызвать RegisterHotKey. Вам не нужно устанавливать ловушку для чего-то столь же простого, как горячая клавиша Ctrl + S, поэтому вместо этого вызовите RegisterHotKey .