How do I get the typechecker to understand inheritance?

I’m trying to figure out inheritance. I got it working at runtime, but I can’t get the typechecker to like it:

--!strict
local base_mt = {p=function(...) print("base_mt.p", ...) end}
base_mt.__index = base_mt
export type Base = typeof(setmetatable({}, base_mt))

local derived_mt = setmetatable({q=function(...) print("derived_mt.q", ...) end}, base_mt)
derived_mt.__index = derived_mt
export type Derived = typeof(setmetatable({}, derived_mt))

local b: Base = setmetatable({}, base_mt)
local d: Derived = setmetatable({}, derived_mt)

b.p("hello") -- base_mt.p hello
d.q("hello") -- derived_mt.q hello
d.p("hello") -- base_mt.p hello

local _bd: Base = d -- TypeError: Expected this to be 'Base', but got 'Derived'

Anyone know how to get the last line to pass typechecker? I consider a Derived instance to also be of type Base, but I don’t know how to tell the typechecker that

1 Like

Solution: Don’t use inheritance.
Its a runtime tax that becomes a real danger very quickly
Magic doesn’t exist; a compiler doesn’t eliminate it, and a VM can’t “magically” optimize it.

Data-driven systems are just superior in everything to objects.

3 Likes

I think if you remove --!strict at the beginning it will work.

2 Likes

You do realize that’s the entire basis of Roblox?

1 Like

What basic?
You mean core scripts using this?
Yeah, that’s really unfortunate, and there’s not much you can do about it, but let’s be optimistic: PlayerModule can be rewritten to not use inefficient technique™ masquerading as “OOP” in a language where one does not exist.
If you are referring to Roblox instances, that would mean an entirely different discussion, as the context currently is about Luau itself rather than the Roblox API.
You could only live so long in lies but will eventually figure out that you are literally getting taxed on performance and being misled by corporate buzzword fluff.
That’s why you should remove the noise und cut ze fluff :raised_fist:

members from the base class aren’t automatically inherited when using metatables. it’s a limitation of the type analyzer. maybe it’ll handle that in the future. for now, you have to do it manually.

export type Derived = typeof(setmetatable({}, derived_mt)) & Base

and a required adjustment:

local d: Derived = setmetatable({}, derived_mt :: any)
3 Likes

Hello! If you’re free to learning new things (that allows inheritance), please try Roblox-TS. I used to think it was very unnecessary until I had my hands on it.

It literally becomes easier to recreate Minecraft or any sort of game that you want on Roblox with convenient inheritance. There are no limitations that comes with metatables.

The linter’s very good, so there are no concerns about type analyzers.

i also tend to prefer DOP, especially when i’m starting from scratch. but it’s not really better or worse than OOP.

inheritance chains are basically equivalent to composition chains. pretty much the only real advantage DOP has over OOP is design flexibility, not code efficiency.

if you’re looking for performance/efficiency, the best thing you can do is optimize your algorithms. the gains there are usually way bigger than any optimization from the VM/interpreter/compiler.

3 Likes

Not sure how inheritance is the basis of ROBLOX. I can make games just fine without it

1 Like

Like another have implied, inheritance isn’t a feature offered on Roblox. Though, basic OOP is still a core of Roblox which you are partly correct on.

Correct, the core of Roblox is based on OOP, but you gotta realize that Roblox itself isn’t based on Luau, as far as I know it’s written in C, meaning there is natural OOP compatibility. Luau does not have that compatibility, therefore OOP should not be used with it.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.