I likely am missing some context, but the comparison to TypeScript's ".d.ts" files seems misplaced. This is a type signature language, but it does not seem to be a type checker.
The comparison to .d.ts files then seems bizarre because that is helpful for language servers¹ to consume types, but there's no proof that say, the implementation matches the type specification.
TypeScript declaration files declare what the types of module exports are. For the most part, a .d.ts file informs the typechecker "the type of module Foo export bar is the interface named Quux". This is not checked, this is simply an assertion. The language server for TypeScript will pick these definitions up, assume they are correct, and provide code completions for those types as if they were correct.
On the other hand, a .ts file, combining types and codes, enables type checking. If the type declarations are incompatible with the code, an error is thrown by TypeScript. While .d.ts files declare types, .ts files verify that the code and the types declare are compatible.
Since .rbs files simply describe the external interface of types and modules, and cannot describe internal variables, I'm not sure how it's doing any type checking.
For example, if I have this code:
module Foo
class Bar
def trivial: () -> String
end
end
What prevents me from writing this:
class Bar
def trivial
return 42
end
end
Or alternatively, this:
class Bar
def trivial
x = some_function_that_might_not_be_declared_in_an_rbs_file()
return x
end
end
Does x have a type? Can I gradually type "class Bar" via type inference, or do I have to declare and keep in sync all my rbs files with my rb files? What happens when the rbs file is out of sync with the rb file?
¹ Language servers are implementations of an IDE protocol for code completion. The trend in programming language tooling is to use Microsoft's Language Server Protocol (https://microsoft.github.io/language-server-protocol/) to provide code completion, semantic navigation, refactoring, etc.
The type checker implementations (eg; Steep, Sorbet) should throw an error at `return 42`. If `some_function_that_might_not_be_declared_in_an_rbs_file` is not known, the behavior may be configurable – it could be assumed to be something like `any` or assumed to be unsafe, and error until you declare that function. I think Sorbet has this configurability today, and I'm not sure about Steep's behavior.
The comparison to ".d.ts" seems apt since both are languages/grammars focused solely on declaring types. How they are interpreted is a different matter of course. TypeScript assumes they are strict declarations of the JavaScript code, while Steep/Sorbet will use the declarations to type check your code.
In your example you would get a type checker error.
The comparison to .d.ts files then seems bizarre because that is helpful for language servers¹ to consume types, but there's no proof that say, the implementation matches the type specification.
TypeScript declaration files declare what the types of module exports are. For the most part, a .d.ts file informs the typechecker "the type of module Foo export bar is the interface named Quux". This is not checked, this is simply an assertion. The language server for TypeScript will pick these definitions up, assume they are correct, and provide code completions for those types as if they were correct.
On the other hand, a .ts file, combining types and codes, enables type checking. If the type declarations are incompatible with the code, an error is thrown by TypeScript. While .d.ts files declare types, .ts files verify that the code and the types declare are compatible.
Since .rbs files simply describe the external interface of types and modules, and cannot describe internal variables, I'm not sure how it's doing any type checking.
For example, if I have this code:
What prevents me from writing this: Or alternatively, this: Does x have a type? Can I gradually type "class Bar" via type inference, or do I have to declare and keep in sync all my rbs files with my rb files? What happens when the rbs file is out of sync with the rb file?¹ Language servers are implementations of an IDE protocol for code completion. The trend in programming language tooling is to use Microsoft's Language Server Protocol (https://microsoft.github.io/language-server-protocol/) to provide code completion, semantic navigation, refactoring, etc.