diff --git a/docs/user-defined-type-function-strings-as-keys.md b/docs/user-defined-type-function-strings-as-keys.md new file mode 100644 index 0000000..38ee054 --- /dev/null +++ b/docs/user-defined-type-function-strings-as-keys.md @@ -0,0 +1,57 @@ +# Implicitly convert strings in type userdata methods that accept a `key` arg and allow strings as keys in the `props` table of `types.newtable` + +## Summary + +This RFC proposes allowing strings as keys for methods on the `table` type userdata in type functions, alongside allowing strings as keys instead of types in the `types.newtable` method of the types library. + +## Motivation + +Currently having to always wrap string literal keys in `types.singleton` is annoying, and becomes especially annoying when using `types.newtable` due to having to write `[types.singleton("key")]` for every single key in the props table. + +This leads to developers having to write the following: + +```luau +types.newtable({ + [types.singleton("meow")] = types.unknown, + [types.singleton("mrrp")] = types.unknown, +}) +``` + +When the following could be written instead, if it were allowed: + +```luau +types.newtable({ + meow = types.unknown, + mrrp = types.unknown, +}) +``` + +## Design + +As a solution, methods that accept a `key` arg on the table `type` instance, and keys in `props` table passed to `types.newtable` will allow strings. With luau implicitly converting these strings to type userdatas. + +### Changed methods + +### `types` Library + +| Name | Current Type | New Type | +| ------------- | ------------- | ------------- | +| `newtable` | (props: {[type]: type \| { read: type, write: type } }?, indexer: { index: type, readresult: type, writeresult: type }?, metatable: type?) -> type | (props: {[type \| string]: type \| { read: type, write: type } }?, indexer: { index: type, readresult: type, writeresult: type }?, metatable: type?) -> type | + +#### Table `type` instance + +| Name | Current Type | New Type | +| ------------- | ------------- | ------------- | +| `setproperty` | (key: type, value: type?) -> () | (key: type \| string, value: type?) -> () | +| `setreadproperty` | (key: type, value: type?) -> () | (key: type \| string, value: type?) -> () | +| `setwriteproperty` | (key: type, value: type?) -> () | (key: type \| string, value: type?) -> () | +| `readproperty` | (key: type) -> type? | (key: type \| string) -> type? | +| `writeproperty` | (key: type) -> type? | (key: type \| string) -> type? | + +## Drawbacks + +Adds implcit behavior, although the behavior is fairly straightforward to understand. + +## Alternatives + +Add new methods to the types library and on the table type instance for accepting strings as keys, or do nothing.