модулей в ocaml/reason стиле (возможно они еще откуда-то пришли типа хаскеля, наверное @kana_sama знает)
типа когда у нас есть некий тип который модуль эскпортирует, и сам по себе этот тип бесполезен, но у нас есть методы модуля которые что-то полезное с этим абстрактным типом делают, например создают его, достают из него данные в некоем виде
тем самым мы абстрагируем то как мы данные храним
фактически что-то типа класса, но состояние хранится извне
я пока сделал объект с полем типа never и пару методов со страшными приведениями
возможно как-то можно покрасивее
type TaskInternal = { title: string }
type TasksInternal = { tasks: Task[] }
export type Task = Readonly<Task>
export type Tasks = { __tasks: never }
export const createTasks = (tasks: Task[]) => fromInternal({ tasks })
export const getTasksAsMap = (tasks: Tasks) => {
const tasksInternal = toInternal(tasks)
const tasksMap = new Map<string, Task>()
tasksInternal.tasks.forEach(task => tasksMap.add(task.title, task))
return tasksMap
}
const fromInternal = (tasksInternal: TasksInternal) => tasks as unknown as Tasks
const toInternal = (tasks: Tasks) => tasks as unknown as TasksInternal
некий чуть более реальный пример
https://www.typescriptlang.org/play/?jsx=1#code/C4TwDgpgBAwghgJwCYEkB2wILXANlAXigG8BYAKCigGMB7DCDALigGdgEBLNAcwG4KVAGa5OYSEhYAiABackSRlKgAfKFJFiJytVNa1cANwhIpA8gF9zFUJCgBxOAFsIAMU4RcqBtjyESNIhIrCzwyOiYvrgA2gC6cVBWFBQQAB5gtAjAULbQYUj+AEoQcEj0uCAAPPkRWDi4AHzW5GkZWTng0I4u7p4FRMRQAPpDPM5uHl4saBDGCInNrZnZdGjsNAglmL1e-gAU1EEhsEFxADRQAO7ywDLTAK5OAEZYAJQs3RN9hA2CUHsAsiUKiBZDHQ5ggB0myQ92oED2fxB-zg1GoFyG1HuCAQF24ilSF0QCFePyg0SRyKgkJpqPRlORxMhrDAonhe3xaSgACorjcZHi0ASeXykLcoABqUW3V4MqCxM5yhJwVgncI+epxOKU2XAixQFUOcY7byReqkw33NAAazQtEuaAtqs+Jtei3Syxo9HWPAgwBNAEFWAGcXAQAB5IQhhBh1VEPZCSaSI09JPvNVILWxH5-NIcVHAWpRBNpyEQ4Lutorb3ZX3+pNB6Nh-aJvofY1p0KnbMEX7AkRwYCYNB7OuB4OhiNRyesEt9V5u5LkVbrPMx6iFjV+eOtqYpr5edMupNF+o54Fz3aWm12h1O-cm094Zor7IDoeMfyVAAqDT2xJYb8s1JXs-iZGE4QRf80QuLEcRAhpyRpSE6QuZC4IQBVyViN0gA
чем это отличается от того, чтобы преобразовывать тип в брендированный unknown?
простую версию таких модулей можно сделать через exist-типы, более мощные требуют чего-то вроде завтипов (а конкретно сигма-тип, обобщение exist-типа)
А какая задача решается, запретить получать определенный тип откуда-то кроме как места объявления этого типа? Я что-то похожее хочу с помощью github.com/rtcad/rtcad/blob/master/src/__tests__/index.ts
Обсуждают сегодня