{"id":15401098,"url":"https://github.com/sunfishcode/annotated-types","last_synced_at":"2026-01-28T16:01:01.070Z","repository":{"id":70208921,"uuid":"393519892","full_name":"sunfishcode/annotated-types","owner":"sunfishcode","description":"An experiment which may turn into a WASI proposal","archived":false,"fork":false,"pushed_at":"2024-12-03T01:14:55.000Z","size":9,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-26T22:10:51.807Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunfishcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-08-06T22:37:47.000Z","updated_at":"2024-12-03T01:14:59.000Z","dependencies_parsed_at":"2025-05-25T17:31:04.107Z","dependency_job_id":"89d353aa-f12e-4ced-b938-53fd50cba205","html_url":"https://github.com/sunfishcode/annotated-types","commit_stats":{"total_commits":10,"total_committers":1,"mean_commits":10.0,"dds":0.0,"last_synced_commit":"f7574e2b0b674b1c2f5a6a68a427b1341b1a51f3"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sunfishcode/annotated-types","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunfishcode%2Fannotated-types","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunfishcode%2Fannotated-types/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunfishcode%2Fannotated-types/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunfishcode%2Fannotated-types/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunfishcode","download_url":"https://codeload.github.com/sunfishcode/annotated-types/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunfishcode%2Fannotated-types/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28846742,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T15:15:36.453Z","status":"ssl_error","status_checked_at":"2026-01-28T15:15:13.020Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T15:56:28.919Z","updated_at":"2026-01-28T16:01:01.051Z","avatar_url":"https://github.com/sunfishcode.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# WASI Type Annotations\n\nThis document describes the `annotated` type, a feature that I may propose to\nbe added to Wasm Components in the future. Here's a quick example of what\n`annotated` could be used for, in a simple [Logo]-like API:\n\n```\nresource turtle {\n    /// Move the turtle forward `how_far` centimeters.\n    forward: function(\n        how_far: annotated\u003cf32, \"unit:cm\"\u003e,\n    );\n\n    /// Turn the turtle left by `how_much`, an angle measured as a fraction of\n    /// a full circle. For example, `0.25` means turn to face to the left, `0.5`\n    /// means turn to face backward, and `-0.25` (or `0.75`) means turn to the\n    /// right.\n    turn_left: function(\n        how_much: annotated\u003cf32, \"math:angle:τ\"\u003e,\n    );\n\n    /// Set the pen color of the turtle to `color`, which is record containing\n    /// red, green, and blue fields.\n    pen_color: function(\n        color: annotated\u003crgb, \"input:color\"\u003e,\n    );\n}\n```\n\nIf this turns out to be useful, one could also imagine adding dedicated syntax,\nwhich could perhaps look like this:\n```\n  how_far: f32 @ unit:cm,\n```\nOr maybe something completely different. Who knows!\n\n## What does `annotated` mean?\n\nIn the component model, a type `annotated\u003cT, type-name\u003e` would be semantically\nequivalent to type `T`. It would have `type-name` as an associated uninterpreted\nstring that describes additional interpretation or intent.\n\nFor example, a parameter that conveys a velocity quantity may have type\n`annotated\u003cu32, \"unit:m/s\"\u003e`, with `m/s` indicating that the\nvalue in meters per second. An email address parameter may have type\n`annotated\u003cstring, \"input:email\"\u003e`.\n\nOne use for these annotations is to guide user interfaces. For example, in a\nGUI, a component requiring a `input:phone` parameter might pop up a specialized\nphone-number entry widget, or a time:UTC` may pop up its date picker. Or a\ncommand-line interface might allow users to type \"4 GiB\" when providing a value\nfor a \"unit:B\" parameter.\n\nAnnotated types *do not perform validation*. For example, `input:email`\ndoes not ensure that string values contain valid email addresses.\n\n### Names:\n\n| `type-name`          | Interface Type  | Meaning                    |\n| -------------------- | --------------- | -------------------------- |\n| `input:search`       | `string`        | [Search]                   |\n| `input:color`        | `record`        | [Color] represented as a record containing `red`, `green`, and `blue` numeric values |\n| `address:email`      | `string`        | [E-mail Address]           |\n| `address:phone`      | `string`        | [Phone number]             |\n| `time:month`         | `u8`            | [Month] index, 1-based     |\n| `time:week`          | `u8`            | [Week] index, 1-based      |\n| `time:weekday`       | `u8`            | Weekday index, 1-based     |\n| `time:UTC`           | `i128`          | UTC time as nanoseconds since 1970-01-01T00:00:00Z minus leap seconds |\n| `time:TAI`           | `i128`          | TAI time as nanoseconds since 1970-01-01T00:00:00Z |\n| `math:angle:τ`       | `f*`            | Mathematical angle measure in [turns] |\n| `math:angle:radians` | `f*`            | Mathematical angle measure in radians |\n| `math:probability`   | `f*`            | Mathematical probability; a value in `[0.0,1.0]` |\n| `math:complex`       | `record { f*, f* }` | A complex number with `real` and `imag` fields |\n| `media:extension`    | `string`        | Filename extension string, excluding the dot |\n| `media:media-type`   | `string`        | A [Media Type] (aka MIME type) name |\n| `media:` + `\u003cmedia type\u003e`  | `*\u003cu8\u003e`   | [Media Type] (aka MIME type) data |\n| `unit:` + `\u003cunit\u003e`   | `n*`            | A quantity, described [below](#unit) |\n| `currency:` + `\u003ccurrency\u003e` | `u*`      | A quantity of currency, described below [below](#currency) |\n| `language:language-tag`    | `string`  | [IETF BCP 47 language tag]   |\n\nAbbreviations:\n - `f*` refers to any floating-point type\n - `u*` refers to any unsigned integer type\n - `s*` refers to any signed integer type\n - `i*` refers to any signed or unsigned integer type\n - `n*` refers to any number type - signed or unsigned integer, or floating-point\n - `*\u003cu8\u003e` refers to any list or stream of `u8`\n\n#### `\u003cunit\u003e`\n\nThe `\u003cunit\u003e` grammar is modeled after the syntax used in the [SI Brochure]\nand Wikipedia pages to describe units and derived units, for example on the\n[SI derived unit] page. For example, a newton metre second per kilogram is\nexpressed as `N⋅m⋅s/kg`.\n\nIt's built on the [SI base units] (except with `g` instead of `kg` so that we\ndon't need to special-case it in the grammar) and the\n[SI derived units with special names]. It also includes a few additional units\nto address specific use cases, but in general it avoids customary units, to\npromote interchange.\n\nTODO: The [SI Brochure] recommends against having two `/` signs not isolated\nfrom each other with parens.\n\n##### `\u003cunit\u003e` Grammar:\n\n```ebnf\nunit = unit , \"⋅\" , factor\n     | unit , \"/\" , factor\n     | factor\n     ;\n\nfactor = base , [ exponent ] ;\nbase = literal\n     | \"(\" , unit , \")\"\n     ;\n\nexponent = [ \"-\" ] , exp_magnitude ;\nexp_magnitude = exp_digit excluding zero , { exp_digit } ;\nexp_digit excluding zero = \"¹\" | \"²\" | \"³\" | \"⁴\" | \"⁵\" | \"⁶\" | \"⁷\" | \"⁸\" | \"⁹\" ;\nexp_digit = \"⁰\" | exp_digit excluding zero\n\nliteral = metric_literal | binary_literal | other_literal ;\nmetric_literal = metric_prefix , metric_symbol ;\nbinary_literal = binary_prefix , binary_symbol ;\n\n; \u003chttps://en.wikipedia.org/wiki/Metric_prefix\u003e\nmetric_prefix = big_metric_prefix | small_metric_prefix ;\nbig_metric_prefix = \"da\" | \"h\" | \"k\" | \"M\" | \"G\" | \"T\" | \"P\" | \"E\" | \"Z\" | \"Y\" ;\nsmall_metric_prefix = \"d\" | \"c\" | \"m\" | \"μ\" | \"n\" | \"p\" | \"f\" | \"a\" | \"z\" | \"y\" ;\n\n; \u003chttps://en.wikipedia.org/wiki/Binary_prefix\u003e\nbinary_prefix = \"Ki\" | \"Mi\" | \"Gi\" | \"Ti\" | \"Pi\" | \"Ei\" | \"Zi\" | \"Yi\" ;\n\nmetric_symbol = simple_unit | named_unit ;\n\n; \u003chttps://en.wikipedia.org/wiki/SI_base_unit\u003e, but with g instead of kg to\n; simplify the grammar.\nsimple_unit = \"s\" | \"m\" | \"g\" | \"A\" | \"K\" | \"mol\" | \"cd\" ;\n\n; \u003chttps://en.wikipedia.org/wiki/SI_derived_unit#Derived_units_with_special_names\u003e\nnamed_unit = \"Hz\" | \"rad\" | \"sr\" | \"N\" | \"Pa\" | \"J\" | \"W\" | \"C\" | \"V\" | \"F\" | \"Ω\"\n           | \"S\" | \"Wb\" | \"T\" | \"H\" | \"°C\" | \"lm\" | \"lx\" | \"Bq\" | \"Gy\" | \"Sv\" | \"kat\" ;\n\n; \u003chttps://en.wikipedia.org/wiki/Byte\u003e\nbinary_symbol = \"B\" ;\n```\n\n#### `\u003ccurrency\u003e`\n\nThe `\u003ccurrency\u003e` must be a standard active alphabetic code from [ISO 4217].\nOther letter sequences are reserved for future use. The integer value\nrepresents a quantity of currency denominated in the [minor units] of the\nspecified currency.\n\n#### Examples\n\nThe `unit:` annotations allow the use of units, which includes:\n - SI units, including base units such as `km`, `s`, `mg`, etc., as well as\n   derived units such as `m/s`, `m/s²`, etc.\n\n - Byte sizes, using `B` to represent bytes, optionally with IEC binary\n   prefixes to represent multiples of larger sizes, for example `MiB`, `GiB`,\n   etc.\n\nThe `schema:` annotations allow the use of [schema.org] property names, which\ninclude many commonly used fields, including:\n\n - [`arrivalTime`], [`checkinTime`], [`endTime`]\n - [`longitude`], [`latitude`],\n - [`reviewRating`], [`reviewBody`]\n\nand many more, as well as records containing property fields, including:\n\n - Creative works: [`CreativeWork`], [`Book`], [`Movie`], [`MusicRecording`], [`Recipe`], [`TVSeries`]\n - Embedded non-text objects: [`AudioObject`], [`ImageObject`], [`VideoObject`]\n - [`Event`]\n - [`Organization`]\n - [`Person`]\n - [`Place`], [`LocalBusiness`], [`Restaurant`]\n - [`Product`], [`Offer`], [`AggregateOffer`]\n - [`Review`], [`AggregateRating`]\n\nand many more.\n\nAn example of a function which defines a product offer:\n```\n/// Define an offer named `name`, with a price of `price` denominated in US\n/// cents (hundreths of US dollars), with availability as described in\n/// `availability`.\noffer: function(\n    name: annotated\u003cstring, \"schema:Text:name\"\u003e,\n    price: annotated\u003cannotated\u003cu64, \"currency:USD\"\u003e, \"schema:Text:price\"\u003e,\n    availability: annotated\u003cstring, \"schema:Text:availability\"\u003e,\n)\n```\n\n[E-mail Address]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#e-mail_address_field\n[Search]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#search_field\n[Phone number]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#phone_number_field\n[Month]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#month\n[Time]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#time\n[Week]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#week\n[Color]: https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types#color_picker_control\n[Media Type]: https://www.iana.org/assignments/media-types/media-types.xhtml\n[U+20A0–U+20CF]: https://www.unicode.org/charts/PDF/U20A0.pdf\n[IETF BCP 47 language tag]: https://www.rfc-editor.org/info/bcp47\n[Logo]: https://en.wikipedia.org/wiki/Logo_(programming_language)\n[schema.org]: https://schema.org\n[`arrivalTime`]: https://schema.org/arrivalTime\n[`checkinTime`]: https://schema.org/checkinTime\n[`endTime`]: https://schema.org/endTime\n[`longitude`]: https://schema.org/longitude\n[`latitude`]: https://schema.org/latitude\n[`CreativeWork`]: https://schema.org/CreativeWork\n[`Book`]: https://schema.org/Book\n[`Movie`]: https://schema.org/Movie\n[`MusicRecording`]: https://schema.org/MusicRecording\n[`Recipe`]: https://schema.org/Recipe\n[`TVSeries`]: https://schema.org/TVSeries\n[`AudioObject`]: https://schema.org/AudioObject\n[`ImageObject`]: https://schema.org/ImageObject\n[`VideoObject`]: https://schema.org/VideoObject\n[`Event`]: https://schema.org/Event\n[`Organization`]: https://schema.org/Organization\n[`Person`]: https://schema.org/Person\n[`Place`]: https://schema.org/Place\n[`LocalBusiness`]: https://schema.org/LocalBusiness\n[`Restaurant`]: https://schema.org/Restaurant\n[`Product`]: https://schema.org/Product\n[`Offer`]: https://schema.org/Offer\n[`AggregateOffer`]: https://schema.org/AggregateOffer\n[`Review`]: https://schema.org/Review\n[`AggregateRating`]: https://schema.org/AggregateRating\n[`reviewRating`]: https://schema.org/reviewRating\n[`reviewBody`]: https://schema.org/reviewBody\n[SI base units]: https://en.wikipedia.org/wiki/SI_base_unit\n[SI derived unit]: https://en.wikipedia.org/wiki/SI_derived_unit\n[SI derived units with special names]: https://en.wikipedia.org/wiki/SI_derived_unit#Derived_units_with_special_names\n[SI Brochure]: https://www.bipm.org/en/publications/si-brochure/\n[Byte]: https://en.wikipedia.org/wiki/Byte\n[Turn]: https://en.wikipedia.org/wiki/Turn_(angle)\n[ISO 4217]: https://en.wikipedia.org/wiki/ISO_4217\n[minor units]: https://en.wikipedia.org/wiki/ISO_4217#Minor_units_of_currency\n[turns]: https://en.wikipedia.org/wiki/Turn_(angle)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunfishcode%2Fannotated-types","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunfishcode%2Fannotated-types","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunfishcode%2Fannotated-types/lists"}