Last active
October 24, 2023 23:24
-
-
Save robyurkowski/7b91a93353ab95f5d75065d1382a5e07 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "dry-types" | |
module DryTS | |
# We use this method to mark a type for inclusion in our generated TS types. | |
def ts_export(_assigned_type) | |
extract_constants! | |
# ... Other stuff for exporting TS | |
end | |
def extract_constants! | |
@__dry_ts_constants ||= {} | |
# constants(false) returns a list of constants for the module that aren't inherited. | |
# We wound up with a solution that was marginally more complex (using `constants(true)` | |
# and removing a list of types inherited from `include Dry.Types()`, which lets us | |
# mix in un-marked up type files and have their types be included, too)... | |
# | |
# ... but this is a lot simpler to show the proof of concept. | |
constants(false).each do |c| | |
# We don't want to accidentally include a non-Type object. | |
next unless (const = const_get(c)).class.ancestors.include?(Dry::Types::Type) | |
@__dry_ts_constants[c] = const.meta(name: c) | |
remove_const(c) | |
end | |
end | |
def const_missing(const) | |
@__dry_ts_constants[const] | |
end | |
def finalize_ts_exports! | |
# Do this one last time because there's no guarantee we ended on a ts_export. | |
extract_constants! | |
@__dry_ts_constants.each do |const_name, const| | |
const_set(const_name, const) | |
end | |
end | |
end | |
module Types | |
extend DryTS | |
include Dry.Types() | |
ts_export UUID = Types::String | |
# Even without exporting this explicitly, it's annotated in the AST for the next type: | |
MyString = Types::String | |
ts_export WeirdMap = Types::Hash.map(MyString, UUID) | |
finalize_ts_exports! | |
end | |
# >> Types::WeirdMap.to_ast | |
# => | |
# [:map, | |
# [[:constrained, [[:nominal, [String, {:name=>:MyString}]], [:predicate, [:type?, [[:type, String], [:input, Undefined]]]]]], | |
# [:constrained, [[:nominal, [String, {:name=>:UUID}]], [:predicate, [:type?, [[:type, String], [:input, Undefined]]]]]], | |
# {:name=>:WeirdMap}]] | |
# >> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment