Typescript гибкие типы - PullRequest
       58

Typescript гибкие типы

0 голосов
/ 20 февраля 2020

Как я могу заставить значение существовать в списке в машинописи, особенно с перечислениями. Является ли это совместимым с определениями типов шрифтов?

enum Friend {
  JOHN,
  SALLY,
  PAUL,
}

type MyFriends = {
   friends: Friend[],
   bestFriend: <> //How can I enforce that this value exists within the supplied list of friends?
}

1 Ответ

2 голосов
/ 20 февраля 2020
enum Friend {
  JOHN,
  SALLY,
  PAUL,
}

// solution at type level
// type constructor
type MyFriends<F extends Friend[]> = {
   friends: F,
   bestFriend: F[number]
}

// make specific instance of it:
type JohnFriends = MyFriends<[Friend.SALLY,Friend.PAUL]>
const johnFriends: JohnFriends = {
    friends: [Friend.SALLY,Friend.PAUL],
    bestFriend: Friend.SALLY // can be only a member of friends array
}
const errorJohnFriends: JohnFriends = {
    friends: [Friend.SALLY,Friend.PAUL],
    bestFriend: Friend.JOHN // error as it should!
}

// solution at value level with value constructor
// additionaly we can make value constructor for proper creating such type of value
const makeFriends = <A extends Friend[], BF extends A[number]>(friends: A, bestFriend: BF): MyFriends<A> => ({
    friends,
    bestFriend
})

// propelry created value of MyFriends
const johnFriends2 = makeFriends([Friend.PAUL, Friend.JOHN], Friend.JOHN); 
const errorJohnFriends2 = makeFriends([Friend.PAUL, Friend.JOHN], Friend.SALLY); // error as it should

То, что мы сделали здесь:

  • MyFriends generi c тип с аргументом Friend, это означает, что мы передаем, какие именно элементы из Friends enum будут быть доступным в friends свойство
  • bestFriend: F[number] - мы говорим, что второе поле может быть только значением, которое существует в массиве friends, благодаря чему мы не можем использовать элемент Enum, который не предусмотрен в первом
...