@quenty/tie 10.27.1 → 10.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [10.28.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@10.27.1...@quenty/tie@10.28.0) (2026-01-06)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Add more typing ([f32615e](https://github.com/Quenty/NevermoreEngine/commit/f32615ec9d846a1a4392a3b21a0f594e8d420b44))
12
+ * Add some strict typing to Tie ([cbdb842](https://github.com/Quenty/NevermoreEngine/commit/cbdb842d6c2a57cf5c1cabab90505cbfec62037b))
13
+
14
+
15
+
16
+
17
+
6
18
  ## [10.27.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@10.27.0...@quenty/tie@10.27.1) (2026-01-05)
7
19
 
8
20
  **Note:** Version bump only for package @quenty/tie
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/tie",
3
- "version": "10.27.1",
3
+ "version": "10.28.0",
4
4
  "description": "Tie allows interfaces to be defined between Lua OOP and Roblox objects.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -53,5 +53,5 @@
53
53
  "publishConfig": {
54
54
  "access": "public"
55
55
  },
56
- "gitHead": "5232cd2c58ca0dcdf591dd8ae78995211da2f3e2"
56
+ "gitHead": "540aa2a77acbb6c9c5967fe4417400a903df2c2c"
57
57
  }
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class TiePropertyDefinition
4
4
  ]=]
@@ -9,16 +9,31 @@ local TieMemberDefinition = require("TieMemberDefinition")
9
9
  local TiePropertyImplementation = require("TiePropertyImplementation")
10
10
  local TiePropertyInterface = require("TiePropertyInterface")
11
11
  local TieRealmUtils = require("TieRealmUtils")
12
+ local TieRealms = require("TieRealms")
12
13
 
13
14
  local TiePropertyDefinition = setmetatable({}, TieMemberDefinition)
14
15
  TiePropertyDefinition.ClassName = "TiePropertyDefinition"
15
16
  TiePropertyDefinition.__index = TiePropertyDefinition
16
17
 
17
- function TiePropertyDefinition.new(tieDefinition, propertyName: string, defaultValue: any, memberTieRealm)
18
+ export type TiePropertyDefinition =
19
+ typeof(setmetatable(
20
+ {} :: {
21
+ _defaultValue: any,
22
+ },
23
+ {} :: typeof({ __index = TieMemberDefinition })
24
+ ))
25
+ & TieMemberDefinition.TieMemberDefinition
26
+
27
+ function TiePropertyDefinition.new(
28
+ tieDefinition: any,
29
+ propertyName: string,
30
+ defaultValue: any,
31
+ memberTieRealm: TieRealms.TieRealm
32
+ ): TiePropertyDefinition
18
33
  assert(TieRealmUtils.isTieRealm(memberTieRealm), "Bad memberTieRealm")
19
34
 
20
- local self =
21
- setmetatable(TieMemberDefinition.new(tieDefinition, propertyName, memberTieRealm), TiePropertyDefinition)
35
+ local self: TiePropertyDefinition =
36
+ setmetatable(TieMemberDefinition.new(tieDefinition, propertyName, memberTieRealm) :: any, TiePropertyDefinition)
22
37
 
23
38
  self._defaultValue = defaultValue
24
39
 
@@ -29,7 +44,7 @@ function TiePropertyDefinition:GetDefaultValue()
29
44
  return self._defaultValue
30
45
  end
31
46
 
32
- function TiePropertyDefinition:IsRequiredForImplementation(currentRealm): boolean
47
+ function TiePropertyDefinition:IsRequiredForImplementation(currentRealm: TieRealms.TieRealm): boolean
33
48
  -- Override
34
49
  if getmetatable(TiePropertyDefinition).IsRequiredForImplementation(self, currentRealm) then
35
50
  if self:GetDefaultValue() ~= nil then
@@ -42,14 +57,14 @@ function TiePropertyDefinition:IsRequiredForImplementation(currentRealm): boolea
42
57
  return false
43
58
  end
44
59
 
45
- function TiePropertyDefinition:Implement(implParent: Instance, initialValue, _actualSelf, tieRealm)
60
+ function TiePropertyDefinition:Implement(implParent: Instance, initialValue, _actualSelf, tieRealm: TieRealms.TieRealm)
46
61
  assert(typeof(implParent) == "Instance", "Bad implParent")
47
62
  assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
48
63
 
49
64
  return TiePropertyImplementation.new(self, implParent, initialValue, tieRealm)
50
65
  end
51
66
 
52
- function TiePropertyDefinition:GetInterface(implParent: Instance, _actualSelf, tieRealm)
67
+ function TiePropertyDefinition:GetInterface(implParent: Instance, _actualSelf, tieRealm: TieRealms.TieRealm)
53
68
  assert(typeof(implParent) == "Instance", "Bad implParent")
54
69
  assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
55
70
 
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class TiePropertyImplementation
4
4
  ]=]
@@ -18,8 +18,18 @@ local TiePropertyImplementation = setmetatable({}, BaseObject)
18
18
  TiePropertyImplementation.ClassName = "TiePropertyImplementation"
19
19
  TiePropertyImplementation.__index = TiePropertyImplementation
20
20
 
21
- function TiePropertyImplementation.new(memberDefinition, folder: Folder, initialValue, _actualSelf)
22
- local self = setmetatable(BaseObject.new(), TiePropertyImplementation)
21
+ export type TiePropertyImplementation =
22
+ typeof(setmetatable(
23
+ {} :: {
24
+ _folder: Instance,
25
+ _memberDefinition: any,
26
+ },
27
+ {} :: typeof({ __index = TiePropertyImplementation })
28
+ ))
29
+ & BaseObject.BaseObject
30
+
31
+ function TiePropertyImplementation.new(memberDefinition, folder: Instance, initialValue, _actualSelf)
32
+ local self = setmetatable(BaseObject.new() :: any, TiePropertyImplementation)
23
33
 
24
34
  self._memberDefinition = assert(memberDefinition, "No memberDefinition")
25
35
  self._folder = assert(folder, "No folder")
@@ -51,8 +61,8 @@ function TiePropertyImplementation.new(memberDefinition, folder: Folder, initial
51
61
  return self
52
62
  end
53
63
 
54
- function TiePropertyImplementation:SetImplementation(implementation)
55
- self._maid._current = nil
64
+ function TiePropertyImplementation.SetImplementation(self: TiePropertyImplementation, implementation)
65
+ self._maid._current = nil :: Maid.Maid?
56
66
 
57
67
  local maid = Maid.new()
58
68
 
@@ -66,7 +76,11 @@ function TiePropertyImplementation:SetImplementation(implementation)
66
76
  self._maid._current = maid
67
77
  end
68
78
 
69
- function TiePropertyImplementation:_updateImplementation(maid, implementation)
79
+ function TiePropertyImplementation._updateImplementation(
80
+ self: TiePropertyImplementation,
81
+ maid: Maid.Maid,
82
+ implementation
83
+ )
70
84
  if ValueObject.isValueObject(implementation) then
71
85
  local checkType = implementation:GetCheckType()
72
86
 
@@ -80,7 +94,7 @@ function TiePropertyImplementation:_updateImplementation(maid, implementation)
80
94
  end
81
95
 
82
96
  if type(implementation) == "table" and implementation.Changed then
83
- local copy = self:_changeToClassIfNeeded("BindableFunction", implementation)
97
+ local copy: BindableFunction = self:_changeToClassIfNeeded("BindableFunction") :: any
84
98
  copy.OnInvoke = function()
85
99
  return TieUtils.encode(implementation)
86
100
  end
@@ -89,14 +103,14 @@ function TiePropertyImplementation:_updateImplementation(maid, implementation)
89
103
  end
90
104
 
91
105
  if typeof(implementation) == "Instance" and implementation:IsA("ValueBase") then
92
- local resultingType = ValueBaseUtils.getValueBaseType(implementation.ClassName)
106
+ local resultingType = ValueBaseUtils.getValueBaseType(implementation.ClassName :: any)
93
107
  if resultingType and AttributeUtils.isValidAttributeType(resultingType) and resultingType ~= "nil" then
94
108
  self:_removeClassIfNeeded()
95
109
 
96
110
  local attributeValue = AttributeValue.new(self._folder, self._memberDefinition:GetMemberName())
97
111
  self:_syncMember(maid, attributeValue, implementation)
98
112
  else
99
- local copy = self:_changeToClassIfNeeded(implementation.ClassName, implementation)
113
+ local copy = self:_changeToClassIfNeeded(implementation.ClassName)
100
114
  self:_syncMember(maid, copy, implementation)
101
115
  copy.Parent = self._folder
102
116
  end
@@ -121,23 +135,28 @@ function TiePropertyImplementation:_updateImplementation(maid, implementation)
121
135
  )
122
136
  end
123
137
 
124
- local copy = self:_changeToClassIfNeeded(className, implementation)
125
- copy.Value = implementation
138
+ local copy = self:_changeToClassIfNeeded(className);
139
+ (copy :: any).Value = implementation
126
140
  copy.Parent = self._folder
127
141
  end
128
142
 
129
- function TiePropertyImplementation:_changeToClassIfNeeded(className)
143
+ function TiePropertyImplementation._changeToClassIfNeeded(self: TiePropertyImplementation, className: string): Instance
130
144
  return TiePropertyImplementationUtils.changeToClassIfNeeded(self._memberDefinition, self._folder, className)
131
145
  end
132
146
 
133
- function TiePropertyImplementation:_removeClassIfNeeded()
147
+ function TiePropertyImplementation._removeClassIfNeeded(self: TiePropertyImplementation)
134
148
  local implementation = self._folder:FindFirstChild(self._memberDefinition:GetMemberName())
135
149
  if implementation then
136
150
  implementation:Destroy()
137
151
  end
138
152
  end
139
153
 
140
- function TiePropertyImplementation:_syncMember(maid, copy, implementation)
154
+ function TiePropertyImplementation._syncMember(
155
+ _self: TiePropertyImplementation,
156
+ maid: Maid.Maid,
157
+ copy: any,
158
+ implementation
159
+ )
141
160
  copy.Value = implementation.Value
142
161
 
143
162
  maid:GiveTask(implementation.Changed:Connect(function()
@@ -1,11 +1,15 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class TiePropertyImplementationUtils
4
4
  ]=]
5
5
 
6
6
  local TiePropertyImplementationUtils = {}
7
7
 
8
- function TiePropertyImplementationUtils.changeToClassIfNeeded(memberDefinition, folder: Folder, className: string)
8
+ function TiePropertyImplementationUtils.changeToClassIfNeeded(
9
+ memberDefinition,
10
+ folder: Instance,
11
+ className: string
12
+ ): Instance
9
13
  local memberName = memberDefinition:GetMemberName()
10
14
  folder:SetAttribute(memberName, nil)
11
15
 
@@ -17,6 +17,7 @@ local String = require("String")
17
17
  local Symbol = require("Symbol")
18
18
  local TieMemberInterface = require("TieMemberInterface")
19
19
  local TiePropertyImplementationUtils = require("TiePropertyImplementationUtils")
20
+ local TieRealms = require("TieRealms")
20
21
  local TieUtils = require("TieUtils")
21
22
  local ValueBaseUtils = require("ValueBaseUtils")
22
23
 
@@ -26,7 +27,12 @@ local TiePropertyInterface = setmetatable({}, TieMemberInterface)
26
27
  TiePropertyInterface.ClassName = "TiePropertyInterface"
27
28
  TiePropertyInterface.__index = TiePropertyInterface
28
29
 
29
- function TiePropertyInterface.new(implParent, adornee: Instance, memberDefinition, interfaceTieRealm)
30
+ function TiePropertyInterface.new(
31
+ implParent: Instance,
32
+ adornee: Instance,
33
+ memberDefinition,
34
+ interfaceTieRealm: TieRealms.TieRealm
35
+ )
30
36
  local self = setmetatable(
31
37
  TieMemberInterface.new(implParent, adornee, memberDefinition, interfaceTieRealm),
32
38
  TiePropertyInterface
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  Base class for a member definition/declaration.
4
4
 
@@ -14,10 +14,23 @@ local TieMemberDefinition = {}
14
14
  TieMemberDefinition.ClassName = "TieMemberDefinition"
15
15
  TieMemberDefinition.__index = TieMemberDefinition
16
16
 
17
- function TieMemberDefinition.new(tieDefinition, memberName: string, memberTieRealm)
17
+ export type TieMemberDefinition = typeof(setmetatable(
18
+ {} :: {
19
+ _tieDefinition: any,
20
+ _memberName: string,
21
+ _memberTieRealm: TieRealms.TieRealm,
22
+ },
23
+ {} :: typeof({ __index = TieMemberDefinition })
24
+ ))
25
+
26
+ function TieMemberDefinition.new(
27
+ tieDefinition: any,
28
+ memberName: string,
29
+ memberTieRealm: TieRealms.TieRealm
30
+ ): TieMemberDefinition
18
31
  assert(TieRealmUtils.isTieRealm(memberTieRealm), "Bad memberTieRealm")
19
32
 
20
- local self = setmetatable({}, TieMemberDefinition)
33
+ local self: TieMemberDefinition = setmetatable({} :: any, TieMemberDefinition)
21
34
 
22
35
  self._tieDefinition = assert(tieDefinition, "No tieDefinition")
23
36
  self._memberName = assert(memberName, "Bad memberName")
@@ -38,7 +51,7 @@ function TieMemberDefinition:GetFriendlyName(): string
38
51
  return string.format("%s.%s", self._tieDefinition:GetName(), self._memberName)
39
52
  end
40
53
 
41
- function TieMemberDefinition:IsRequiredForInterface(currentRealm): boolean
54
+ function TieMemberDefinition:IsRequiredForInterface(currentRealm: TieRealms.TieRealm): boolean
42
55
  assert(TieRealmUtils.isTieRealm(currentRealm), "Bad currentRealm")
43
56
 
44
57
  if self._memberTieRealm == TieRealms.SHARED then
@@ -51,7 +64,7 @@ function TieMemberDefinition:IsRequiredForInterface(currentRealm): boolean
51
64
  end
52
65
  end
53
66
 
54
- function TieMemberDefinition:IsAllowedOnInterface(currentRealm): boolean
67
+ function TieMemberDefinition:IsAllowedOnInterface(currentRealm: TieRealms.TieRealm): boolean
55
68
  assert(TieRealmUtils.isTieRealm(currentRealm), "Bad currentRealm")
56
69
 
57
70
  if self._memberTieRealm == TieRealms.SHARED then
@@ -64,7 +77,7 @@ function TieMemberDefinition:IsAllowedOnInterface(currentRealm): boolean
64
77
  end
65
78
  end
66
79
 
67
- function TieMemberDefinition:IsRequiredForImplementation(currentRealm): boolean
80
+ function TieMemberDefinition:IsRequiredForImplementation(currentRealm: TieRealms.TieRealm): boolean
68
81
  assert(TieRealmUtils.isTieRealm(currentRealm), "Bad currentRealm")
69
82
 
70
83
  if currentRealm == TieRealms.SHARED then
@@ -77,7 +90,7 @@ function TieMemberDefinition:IsRequiredForImplementation(currentRealm): boolean
77
90
  end
78
91
  end
79
92
 
80
- function TieMemberDefinition:IsAllowedForImplementation(currentRealm): boolean
93
+ function TieMemberDefinition:IsAllowedForImplementation(currentRealm: TieRealms.TieRealm): boolean
81
94
  assert(TieRealmUtils.isTieRealm(currentRealm), "Bad currentRealm")
82
95
 
83
96
  if self._memberTieRealm == TieRealms.SHARED then
@@ -90,7 +103,7 @@ function TieMemberDefinition:IsAllowedForImplementation(currentRealm): boolean
90
103
  end
91
104
  end
92
105
 
93
- function TieMemberDefinition:GetMemberTieRealm()
106
+ function TieMemberDefinition:GetMemberTieRealm(): TieRealms.TieRealm
94
107
  return self._memberTieRealm
95
108
  end
96
109
 
@@ -9,12 +9,18 @@ local Rx = require("Rx")
9
9
  local RxBrioUtils = require("RxBrioUtils")
10
10
  local RxInstanceUtils = require("RxInstanceUtils")
11
11
  local TieRealmUtils = require("TieRealmUtils")
12
+ local TieRealms = require("TieRealms")
12
13
 
13
14
  local TieMemberInterface = {}
14
15
  TieMemberInterface.ClassName = "TieMemberInterface"
15
16
  TieMemberInterface.__index = TieMemberInterface
16
17
 
17
- function TieMemberInterface.new(implParent, adornee, memberDefinition, interfaceTieRealm)
18
+ function TieMemberInterface.new(
19
+ implParent: Instance?,
20
+ adornee: Instance?,
21
+ memberDefinition,
22
+ interfaceTieRealm: TieRealms.TieRealm
23
+ )
18
24
  assert(TieRealmUtils.isTieRealm(interfaceTieRealm), "Bad interfaceTieRealm")
19
25
 
20
26
  local self = setmetatable({}, TieMemberInterface)
@@ -31,7 +31,7 @@ end
31
31
 
32
32
  @return TieRealm
33
33
  ]=]
34
- function TieRealmUtils.inferTieRealm(): "server" | "client"
34
+ function TieRealmUtils.inferTieRealm(): TieRealms.TieRealm
35
35
  if RunService:IsServer() then
36
36
  return TieRealms.SERVER
37
37
  elseif RunService:IsClient() then
@@ -12,9 +12,9 @@ local Table = require("Table")
12
12
  export type TieRealm = "shared" | "client" | "server"
13
13
 
14
14
  export type TieRealms = {
15
- SHARED: "shared",
16
- CLIENT: "client",
17
- SERVER: "server",
15
+ SHARED: TieRealm,
16
+ CLIENT: TieRealm,
17
+ SERVER: TieRealm,
18
18
  }
19
19
 
20
20
  return Table.readonly({
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  Constructs a new interface declaration which allows for interface usage
4
4
  between both Roblox API users and OOP users, as well as without accessing a
@@ -48,6 +48,7 @@ local require = require(script.Parent.loader).load(script)
48
48
  local Brio = require("Brio")
49
49
  local Maid = require("Maid")
50
50
  local Observable = require("Observable")
51
+ local Promise = require("Promise")
51
52
  local Rx = require("Rx")
52
53
  local RxBrioUtils = require("RxBrioUtils")
53
54
  local RxCollectionServiceUtils = require("RxCollectionServiceUtils")
@@ -67,19 +68,55 @@ local ValueObject = require("ValueObject")
67
68
 
68
69
  local UNSET_VALUE = Symbol.named("unsetValue")
69
70
 
71
+ local IMPL_CLIENT_SET = table.freeze({
72
+ ["Configuration"] = true,
73
+ })
74
+
75
+ local IMPL_SERVER_SET = table.freeze({
76
+ ["Camera"] = true,
77
+ })
78
+
79
+ local IMPL_SHARED_SET = table.freeze({
80
+ ["Camera"] = true,
81
+ ["Configuration"] = true,
82
+ })
83
+
70
84
  export type TieRealm = TieRealms.TieRealm
71
85
 
72
86
  local TieDefinition = {}
73
87
  TieDefinition.ClassName = "TieDefinition"
74
88
  TieDefinition.__index = TieDefinition
75
89
 
90
+ export type TieDefinitionType = "method" | "signal" | "property"
91
+ export type TieDefinitionTypes = {
92
+ METHOD: TieDefinitionType,
93
+ SIGNAL: TieDefinitionType,
94
+ PROPERTY: TieDefinitionType,
95
+ }
76
96
  TieDefinition.Types = Table.readonly({
77
97
  METHOD = Symbol.named("method"),
78
98
  SIGNAL = Symbol.named("signal"),
79
99
  PROPERTY = Symbol.named("property"), -- will default to nil
80
- })
100
+ }) :: TieDefinitionTypes
101
+
102
+ TieDefinition.Realms = TieRealms :: TieRealms.TieRealms
81
103
 
82
- TieDefinition.Realms = TieRealms
104
+ export type TieDefinition<T> = typeof(setmetatable(
105
+ {} :: {
106
+ _definitionName: string,
107
+ _memberMap: { [string]: any },
108
+ _defaultTieRealm: TieRealms.TieRealm,
109
+ _validContainerNameSetWeakCache: { [TieRealms.TieRealm]: { [string]: boolean } },
110
+
111
+ Server: TieDefinition<T>,
112
+ Client: TieDefinition<T>,
113
+ },
114
+ {} :: typeof({ __index = TieDefinition })
115
+ ))
116
+
117
+ export type TieMemberMap = {
118
+ [string | TieRealms.TieRealm]: TieDefinitionType | TieMemberMap | any,
119
+ }
83
120
 
84
121
  --[=[
85
122
  Constructs a new TieDefinition with the given members
@@ -88,11 +125,11 @@ TieDefinition.Realms = TieRealms
88
125
  @param members any
89
126
  @return TieDefinition
90
127
  ]=]
91
- function TieDefinition.new(definitionName: string, members)
92
- local self = setmetatable({}, TieDefinition)
128
+ function TieDefinition.new<T>(definitionName: string, members: TieMemberMap): TieDefinition<T>
129
+ local self: TieDefinition<T> = setmetatable({} :: any, TieDefinition)
93
130
 
94
131
  self._definitionName = assert(definitionName, "No definitionName")
95
- self._validContainerNameSetWeakCache = setmetatable({}, { __mode = "kv" })
132
+ self._validContainerNameSetWeakCache = setmetatable({} :: any, { __mode = "kv" })
96
133
  self._memberMap = {}
97
134
  self._defaultTieRealm = TieRealms.SHARED
98
135
 
@@ -103,18 +140,18 @@ function TieDefinition.new(definitionName: string, members)
103
140
  _defaultTieRealm = TieRealms.SERVER,
104
141
  }, {
105
142
  __index = self,
106
- })
143
+ }) :: any
107
144
 
108
145
  self.Client = setmetatable({
109
146
  _defaultTieRealm = TieRealms.CLIENT,
110
147
  }, {
111
148
  __index = self,
112
- })
149
+ }) :: any
113
150
 
114
151
  return self
115
152
  end
116
153
 
117
- function TieDefinition:_addMembers(members, realm)
154
+ function TieDefinition._addMembers<T>(self: TieDefinition<T>, members, realm)
118
155
  for memberName, memberTypeOrDefaultValue in members do
119
156
  if TieRealmUtils.isTieRealm(memberName) then
120
157
  self:_addMembers(memberTypeOrDefaultValue, memberName)
@@ -131,7 +168,7 @@ function TieDefinition:_addMembers(members, realm)
131
168
  end
132
169
  end
133
170
 
134
- function TieDefinition:_addMember(memberName: string, memberTypeOrDefaultValue, realm: TieRealm)
171
+ function TieDefinition._addMember<T>(self: TieDefinition<T>, memberName: string, memberTypeOrDefaultValue, realm: TieRealm)
135
172
  if memberTypeOrDefaultValue == TieDefinition.Types.METHOD then
136
173
  self._memberMap[memberName] = TieMethodDefinition.new(self, memberName, realm)
137
174
  elseif memberTypeOrDefaultValue == TieDefinition.Types.SIGNAL then
@@ -147,15 +184,20 @@ end
147
184
  Gets all valid interfaces for this adornee
148
185
  @param adornee Instance
149
186
  @param tieRealm TieRealm?
150
- @return { TieInterface }
187
+ @return { TieInterface<T> }
151
188
  ]=]
152
- function TieDefinition:GetImplementations(adornee: Instance, tieRealm: TieRealm?)
189
+ function TieDefinition.GetImplementations<T>(
190
+ self: TieDefinition<T>,
191
+ adornee: Instance,
192
+ tieRealm: TieRealm?
193
+ ): { TieInterface.TieInterface<T> }
153
194
  assert(typeof(adornee) == "Instance", "Bad adornee")
154
195
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
155
196
 
156
197
  tieRealm = tieRealm or self._defaultTieRealm
198
+ assert(tieRealm, "Typechecking assertion")
157
199
 
158
- local implementations = {}
200
+ local implementations: { TieInterface.TieInterface<T> } = {}
159
201
 
160
202
  for _, item in self:GetImplementationParents(adornee, tieRealm) do
161
203
  table.insert(implementations, TieInterface.new(self, item, nil, tieRealm))
@@ -164,7 +206,7 @@ function TieDefinition:GetImplementations(adornee: Instance, tieRealm: TieRealm?
164
206
  return implementations
165
207
  end
166
208
 
167
- function TieDefinition:GetNewImplClass(tieRealm: TieRealm): string
209
+ function TieDefinition.GetNewImplClass<T>(_self: TieDefinition<T>, tieRealm: TieRealm): string
168
210
  assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
169
211
 
170
212
  if tieRealm == TieRealms.CLIENT then
@@ -174,20 +216,7 @@ function TieDefinition:GetNewImplClass(tieRealm: TieRealm): string
174
216
  end
175
217
  end
176
218
 
177
- local IMPL_CLIENT_SET = table.freeze({
178
- ["Configuration"] = true,
179
- })
180
-
181
- local IMPL_SERVER_SET = table.freeze({
182
- ["Camera"] = true,
183
- })
184
-
185
- local IMPL_SHARED_SET = table.freeze({
186
- ["Camera"] = true,
187
- ["Configuration"] = true,
188
- })
189
-
190
- function TieDefinition:GetImplClassSet(tieRealm: TieRealm): { [string]: boolean }
219
+ function TieDefinition.GetImplClassSet<T>(_self: TieDefinition<T>, tieRealm: TieRealm): { [string]: boolean }
191
220
  if tieRealm == TieRealms.CLIENT then
192
221
  -- Shared implements both...
193
222
  return IMPL_CLIENT_SET
@@ -200,11 +229,16 @@ function TieDefinition:GetImplClassSet(tieRealm: TieRealm): { [string]: boolean
200
229
  end
201
230
  end
202
231
 
203
- function TieDefinition:GetImplementationParents(adornee: BasePart, tieRealm: TieRealm?): { Instance }
232
+ function TieDefinition.GetImplementationParents<T>(
233
+ self: TieDefinition<T>,
234
+ adornee: Instance,
235
+ tieRealm: TieRealm?
236
+ ): { Instance }
204
237
  assert(typeof(adornee) == "Instance", "Bad adornee")
205
238
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
206
239
 
207
240
  tieRealm = tieRealm or self._defaultTieRealm
241
+ assert(tieRealm, "Typechecking assertion")
208
242
 
209
243
  local validContainerNameSet = self:GetValidContainerNameSet(tieRealm)
210
244
 
@@ -226,17 +260,21 @@ end
226
260
 
227
261
  @param adornee Instance
228
262
  @param tieRealm TieRealm?
229
- @return Observable<Brio<TieInterface>>
263
+ @return Observable<Brio<TieImplementation<T>>>
230
264
  ]=]
231
- function TieDefinition:ObserveChildrenBrio(adornee: Instance, tieRealm: TieRealm?)
265
+ function TieDefinition.ObserveChildrenBrio<T>(
266
+ self: TieDefinition<T>,
267
+ adornee: Instance,
268
+ tieRealm: TieRealm?
269
+ ): Observable.Observable<Brio.Brio<TieImplementation.TieImplementation<T>>>
232
270
  assert(typeof(adornee) == "Instance", "Bad adornee")
233
271
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
234
272
 
235
273
  return RxInstanceUtils.observeChildrenBrio(adornee):Pipe({
236
274
  RxBrioUtils.flatMapBrio(function(child)
237
275
  return self:ObserveBrio(child, tieRealm)
238
- end),
239
- })
276
+ end) :: any,
277
+ }) :: any
240
278
  end
241
279
 
242
280
  --[=[
@@ -246,7 +284,11 @@ end
246
284
  @param tieRealm TieRealm?
247
285
  @return Promise<TieInterface>
248
286
  ]=]
249
- function TieDefinition:Promise(adornee: Instance, tieRealm: TieRealm?)
287
+ function TieDefinition.Promise<T>(
288
+ self: TieDefinition<T>,
289
+ adornee: Instance,
290
+ tieRealm: TieRealm?
291
+ ): Promise.Promise<TieInterface.TieInterface<T>>
250
292
  assert(typeof(adornee) == "Instance", "Bad adornee")
251
293
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
252
294
 
@@ -255,11 +297,22 @@ function TieDefinition:Promise(adornee: Instance, tieRealm: TieRealm?)
255
297
  return Rx.toPromise(self:Observe(adornee, tieRealm):Pipe({
256
298
  Rx.where(function(value)
257
299
  return value ~= nil
258
- end),
259
- }))
300
+ end) :: any,
301
+ }) :: any)
260
302
  end
261
303
 
262
- function TieDefinition:Wait(adornee: Instance, tieRealm: TieRealm?)
304
+ --[=[
305
+ Waits for the implementation
306
+
307
+ @param adornee Adornee
308
+ @param tieRealm TieRealm?
309
+ @return TieInterface
310
+ ]=]
311
+ function TieDefinition.Wait<T>(
312
+ self: TieDefinition<T>,
313
+ adornee: Instance,
314
+ tieRealm: TieRealm?
315
+ ): TieInterface.TieInterface<T>
263
316
  return self:Promise(adornee, tieRealm):Wait()
264
317
  end
265
318
 
@@ -270,16 +323,20 @@ end
270
323
  @param tieRealm TieRealm?
271
324
  @return { TieInterface }
272
325
  ]=]
273
- function TieDefinition:GetChildren(adornee: Instance, tieRealm: TieRealm?)
326
+ function TieDefinition.GetChildren<T>(
327
+ self: TieDefinition<T>,
328
+ adornee: Instance,
329
+ tieRealm: TieRealm?
330
+ ): { TieInterface.TieInterface<T> }
274
331
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
275
332
  assert(typeof(adornee) == "Instance", "Bad adornee")
276
333
 
277
- local implementations = {}
334
+ local implementations: { TieInterface.TieInterface<T> } = {}
278
335
 
279
336
  -- TODO: Make this faster
280
337
  for _, item in adornee:GetChildren() do
281
338
  for _, option in self:GetImplementations(item, tieRealm) do
282
- table.insert(implementations, option)
339
+ table.insert(implementations, option :: any)
283
340
  end
284
341
  end
285
342
 
@@ -293,7 +350,11 @@ end
293
350
  @param tieRealm TieRealm?
294
351
  @return TieInterface | nil
295
352
  ]=]
296
- function TieDefinition:Find(adornee: Instance, tieRealm: TieRealm?)
353
+ function TieDefinition.Find<T>(
354
+ self: TieDefinition<T>,
355
+ adornee: Instance,
356
+ tieRealm: TieRealm?
357
+ ): TieInterface.TieInterface<T>?
297
358
  assert(typeof(adornee) == "Instance", "Bad adornee")
298
359
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
299
360
 
@@ -307,15 +368,19 @@ end
307
368
  @param tieRealm TieRealm?
308
369
  @return TieInterface | nil
309
370
  ]=]
310
- function TieDefinition:ObserveAllTaggedBrio(tagName: string, tieRealm: TieRealm?)
371
+ function TieDefinition.ObserveAllTaggedBrio<T>(
372
+ self: TieDefinition<T>,
373
+ tagName: string,
374
+ tieRealm: TieRealm?
375
+ ): Observable.Observable<Brio.Brio<TieInterface.TieInterface<T>>>
311
376
  assert(type(tagName) == "string", "Bad tagName")
312
377
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
313
378
 
314
379
  return RxCollectionServiceUtils.observeTaggedBrio(tagName):Pipe({
315
380
  RxBrioUtils.flatMapBrio(function(instance)
316
381
  return self:ObserveBrio(instance, tieRealm)
317
- end),
318
- })
382
+ end) :: any,
383
+ }) :: any
319
384
  end
320
385
 
321
386
  --[=[
@@ -324,11 +389,16 @@ end
324
389
  @param tieRealm TieRealm?
325
390
  @return TieInterface
326
391
  ]=]
327
- function TieDefinition:FindFirstImplementation(adornee: Instance, tieRealm: TieRealm?)
392
+ function TieDefinition.FindFirstImplementation<T>(
393
+ self: TieDefinition<T>,
394
+ adornee: Instance,
395
+ tieRealm: TieRealm?
396
+ ): TieInterface.TieInterface<T>?
328
397
  assert(typeof(adornee) == "Instance", "Bad adornee")
329
398
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
330
399
 
331
400
  tieRealm = tieRealm or self._defaultTieRealm
401
+ assert(tieRealm, "Typechecking assertion")
332
402
 
333
403
  local validContainerNameSet = self:GetValidContainerNameSet(tieRealm)
334
404
  for _, item in adornee:GetChildren() do
@@ -348,11 +418,12 @@ end
348
418
  @param tieRealm TieRealm?
349
419
  @return boolean
350
420
  ]=]
351
- function TieDefinition:HasImplementation(adornee: Instance, tieRealm: TieRealm?)
421
+ function TieDefinition.HasImplementation<T>(self: TieDefinition<T>, adornee: Instance, tieRealm: TieRealm?): boolean
352
422
  assert(typeof(adornee) == "Instance", "Bad adornee")
353
423
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
354
424
 
355
425
  tieRealm = tieRealm or self._defaultTieRealm
426
+ assert(tieRealm, "Typechecking assertion")
356
427
 
357
428
  -- TODO: Maybe something faster
358
429
  for containerName, _ in pairs(self:GetValidContainerNameSet(tieRealm)) do
@@ -375,18 +446,22 @@ end
375
446
  @param tieRealm TieRealm?
376
447
  @return Observable<boolean>>
377
448
  ]=]
378
- function TieDefinition:ObserveIsImplemented(adornee: Instance, tieRealm: TieRealm?): Observable.Observable<boolean>
449
+ function TieDefinition.ObserveIsImplemented<T>(
450
+ self: TieDefinition<T>,
451
+ adornee: Instance,
452
+ tieRealm: TieRealm?
453
+ ): Observable.Observable<boolean>
379
454
  assert(typeof(adornee) == "Instance", "Bad adornee")
380
455
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
381
456
 
382
457
  return self:ObserveLastImplementationBrio(adornee, tieRealm):Pipe({
383
458
  RxBrioUtils.map(function(result)
384
459
  return result and true or false
385
- end),
386
- RxBrioUtils.emitOnDeath(false),
460
+ end) :: any,
461
+ RxBrioUtils.emitOnDeath(false) :: any,
387
462
  Rx.defaultsTo(false) :: any,
388
463
  Rx.distinct() :: any,
389
- })
464
+ }) :: any
390
465
  end
391
466
 
392
467
  --[=[
@@ -395,7 +470,8 @@ end
395
470
  @param tieRealm TieRealm?
396
471
  @return Observable<boolean>>
397
472
  ]=]
398
- function TieDefinition:ObserveIsImplementation(
473
+ function TieDefinition.ObserveIsImplementation<T>(
474
+ self: TieDefinition<T>,
399
475
  implParent: Instance,
400
476
  tieRealm: TieRealm?
401
477
  ): Observable.Observable<boolean>
@@ -403,15 +479,16 @@ function TieDefinition:ObserveIsImplementation(
403
479
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
404
480
 
405
481
  tieRealm = tieRealm or self._defaultTieRealm
482
+ assert(tieRealm, "Typechecking assertion")
406
483
 
407
- return self:_observeImplementation(implParent, tieRealm):Pipe({
484
+ return self:_observeImplementedInterface(implParent, tieRealm):Pipe({
408
485
  RxBrioUtils.map(function(result)
409
486
  return result and true or false
410
- end),
411
- RxBrioUtils.emitOnDeath(false),
412
- Rx.defaultsTo(false),
413
- Rx.distinct(),
414
- })
487
+ end) :: any,
488
+ RxBrioUtils.emitOnDeath(false) :: any,
489
+ Rx.defaultsTo(false) :: any,
490
+ Rx.distinct() :: any,
491
+ }) :: any
415
492
  end
416
493
 
417
494
  --[=[
@@ -421,7 +498,8 @@ end
421
498
  @param tieRealm TieRealm?
422
499
  @return Observable<boolean>>
423
500
  ]=]
424
- function TieDefinition:ObserveIsImplementedOn(
501
+ function TieDefinition.ObserveIsImplementedOn<T>(
502
+ self: TieDefinition<T>,
425
503
  implParent: Instance,
426
504
  adornee: Instance,
427
505
  tieRealm: TieRealm?
@@ -431,20 +509,21 @@ function TieDefinition:ObserveIsImplementedOn(
431
509
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
432
510
 
433
511
  tieRealm = tieRealm or self._defaultTieRealm
512
+ assert(tieRealm, "Typechecking assertion")
434
513
 
435
514
  return RxInstanceUtils.observePropertyBrio(implParent, "Parent", function(parent)
436
515
  return parent == adornee
437
516
  end):Pipe({
438
517
  RxBrioUtils.switchMapBrio(function()
439
- return self:_observeImplementation(implParent, tieRealm)
440
- end),
518
+ return self:_observeImplementedInterface(implParent, tieRealm)
519
+ end) :: any,
441
520
  RxBrioUtils.map(function(result)
442
521
  return result and true or false
443
- end),
444
- RxBrioUtils.emitOnDeath(false),
445
- Rx.defaultsTo(false),
446
- Rx.distinct(),
447
- })
522
+ end) :: any,
523
+ RxBrioUtils.emitOnDeath(false) :: any,
524
+ Rx.defaultsTo(false) :: any,
525
+ Rx.distinct() :: any,
526
+ }) :: any
448
527
  end
449
528
 
450
529
  --[=[
@@ -452,20 +531,25 @@ end
452
531
 
453
532
  @param adornee Instance
454
533
  @param tieRealm TieRealm?
455
- @return Observable<Brio<TieImplementation<T>>>
534
+ @return Observable<Brio<TieInterface<T>>>
456
535
  ]=]
457
- function TieDefinition:ObserveBrio(adornee: Instance, tieRealm: TieRealm?)
536
+ function TieDefinition.ObserveBrio<T>(
537
+ self: TieDefinition<T>,
538
+ adornee: Instance,
539
+ tieRealm: TieRealm?
540
+ ): Observable.Observable<Brio.Brio<TieInterface.TieInterface<T>>>
458
541
  assert(typeof(adornee) == "Instance", "Bad adornee")
459
542
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
460
543
 
461
544
  tieRealm = tieRealm or self._defaultTieRealm
545
+ assert(tieRealm, "Typechecking assertion")
462
546
 
463
547
  return self:ObserveValidContainerChildrenBrio(adornee, tieRealm):Pipe({
464
548
  RxBrioUtils.switchMapBrio(function(implParent)
465
- return self:_observeImplementation(implParent, tieRealm)
466
- end),
467
- RxBrioUtils.onlyLastBrioSurvives(),
468
- })
549
+ return self:_observeImplementedInterface(implParent, tieRealm)
550
+ end) :: any,
551
+ RxBrioUtils.onlyLastBrioSurvives() :: any,
552
+ }) :: any
469
553
  end
470
554
 
471
555
  --[=[
@@ -473,15 +557,19 @@ end
473
557
 
474
558
  @param adornee Instance
475
559
  @param tieRealm TieRealm?
476
- @return Observable<TieImplementation<T> | nil>>
560
+ @return Observable<TieInterface<T>?>>
477
561
  ]=]
478
- function TieDefinition:Observe(adornee: Instance, tieRealm: TieRealm?)
562
+ function TieDefinition.Observe<T>(
563
+ self: TieDefinition<T>,
564
+ adornee: Instance,
565
+ tieRealm: TieRealm?
566
+ ): Observable.Observable<TieInterface.TieInterface<T>?>
479
567
  assert(typeof(adornee) == "Instance", "Bad adornee")
480
568
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
481
569
 
482
570
  return self:ObserveBrio(adornee, tieRealm):Pipe({
483
- RxStateStackUtils.topOfStack(),
484
- })
571
+ RxStateStackUtils.topOfStack() :: any,
572
+ }) :: any
485
573
  end
486
574
 
487
575
  TieDefinition.ObserveLastImplementation = TieDefinition.Observe
@@ -491,22 +579,38 @@ TieDefinition.ObserveLastImplementationBrio = TieDefinition.ObserveBrio
491
579
  Observes valid implementations wrapped in a brio if it exists.
492
580
  @param adornee Instance
493
581
  @param tieRealm TieRealm?
494
- @return Observable<Brio<TieImplementation<T>>>
582
+ @return Observable<Brio<TieInterface<T>>>
495
583
  ]=]
496
- function TieDefinition:ObserveImplementationsBrio(adornee: Instance, tieRealm: TieRealm?)
584
+ function TieDefinition.ObserveImplementationsBrio<T>(
585
+ self: TieDefinition<T>,
586
+ adornee: Instance,
587
+ tieRealm: TieRealm?
588
+ ): Observable.Observable<Brio.Brio<TieInterface.TieInterface<T>>>
497
589
  assert(typeof(adornee) == "Instance", "Bad adornee")
498
590
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
499
591
 
500
592
  tieRealm = tieRealm or self._defaultTieRealm
593
+ assert(tieRealm, "Typechecking assertion")
501
594
 
502
595
  return self:ObserveValidContainerChildrenBrio(adornee, tieRealm):Pipe({
503
596
  RxBrioUtils.flatMapBrio(function(implParent)
504
- return self:_observeImplementation(implParent, tieRealm)
505
- end),
506
- })
597
+ return self:_observeImplementedInterface(implParent, tieRealm)
598
+ end) :: any,
599
+ }) :: any
507
600
  end
508
601
 
509
- function TieDefinition:ObserveValidContainerChildrenBrio(adornee: Instance, tieRealm: TieRealm?)
602
+ --[=[
603
+ Observes valid container children for this adornee that could be implementations.
604
+
605
+ @param adornee Instance
606
+ @param tieRealm TieRealm
607
+ @return Observable<Brio<Instance>>
608
+ ]=]
609
+ function TieDefinition.ObserveValidContainerChildrenBrio<T>(
610
+ self: TieDefinition<T>,
611
+ adornee: Instance,
612
+ tieRealm: TieRealm
613
+ ): Observable.Observable<Brio.Brio<Instance>>
510
614
  assert(typeof(adornee) == "Instance", "Bad adornee")
511
615
  assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
512
616
 
@@ -519,7 +623,11 @@ function TieDefinition:ObserveValidContainerChildrenBrio(adornee: Instance, tieR
519
623
  end)
520
624
  end
521
625
 
522
- function TieDefinition:_observeImplementation(implParent: Instance, tieRealm: TieRealm?)
626
+ function TieDefinition._observeImplementedInterface<T>(
627
+ self: TieDefinition<T>,
628
+ implParent: Instance,
629
+ tieRealm: TieRealm
630
+ ): Observable.Observable<Brio.Brio<TieInterface.TieInterface<T>>>
523
631
  assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
524
632
 
525
633
  return Observable.new(function(sub)
@@ -580,7 +688,7 @@ function TieDefinition:_observeImplementation(implParent: Instance, tieRealm: Ti
580
688
  update()
581
689
 
582
690
  return maid
583
- end)
691
+ end) :: any
584
692
  end
585
693
 
586
694
  --[=[
@@ -596,7 +704,12 @@ end
596
704
  @param tieRealm TieRealm?
597
705
  @return TieImplementation<T>
598
706
  ]=]
599
- function TieDefinition:Implement(adornee: Instance, implementer, tieRealm: TieRealm?)
707
+ function TieDefinition.Implement<T>(
708
+ self: TieDefinition<T>,
709
+ adornee: Instance,
710
+ implementer: T,
711
+ tieRealm: TieRealm?
712
+ ): TieImplementation.TieImplementation<T>
600
713
  assert(typeof(adornee) == "Instance", "Bad adornee")
601
714
  assert(type(implementer) == "table" or implementer == nil, "Bad implementer")
602
715
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
@@ -620,11 +733,12 @@ end
620
733
  @param tieRealm TieRealm?
621
734
  @return TieInterface<T>
622
735
  ]=]
623
- function TieDefinition:Get(adornee: Instance, tieRealm: TieRealm?)
736
+ function TieDefinition.Get<T>(self: TieDefinition<T>, adornee: Instance, tieRealm: TieRealm?): TieInterface.TieInterface<T>
624
737
  assert(typeof(adornee) == "Instance", "Bad adornee")
625
738
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
626
739
 
627
740
  tieRealm = tieRealm or self._defaultTieRealm
741
+ assert(tieRealm, "Typechecking assertion")
628
742
 
629
743
  return TieInterface.new(self, nil, adornee, tieRealm)
630
744
  end
@@ -633,7 +747,7 @@ end
633
747
  Gets the name of the definition
634
748
  @return string
635
749
  ]=]
636
- function TieDefinition:GetName(): string
750
+ function TieDefinition.GetName<T>(self: TieDefinition<T>): string
637
751
  return self._definitionName
638
752
  end
639
753
 
@@ -643,7 +757,7 @@ end
643
757
  @param tieRealm TieRealm
644
758
  @return { [string]: boolean }
645
759
  ]=]
646
- function TieDefinition:GetValidContainerNameSet(tieRealm: TieRealm?): { [string]: boolean }
760
+ function TieDefinition.GetValidContainerNameSet<T>(self: TieDefinition<T>, tieRealm: TieRealm): { [string]: boolean }
647
761
  -- TODO: Still generate unique datamodel key here?
648
762
  if self._validContainerNameSetWeakCache[tieRealm] then
649
763
  return self._validContainerNameSetWeakCache[tieRealm]
@@ -683,7 +797,7 @@ end
683
797
  @param tieRealm TieRealm
684
798
  @return string
685
799
  ]=]
686
- function TieDefinition:GetNewContainerName(tieRealm: TieRealm): string
800
+ function TieDefinition.GetNewContainerName<T>(self: TieDefinition<T>, tieRealm: TieRealm): string
687
801
  assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
688
802
 
689
803
  -- TODO: Handle server/actor
@@ -700,7 +814,7 @@ function TieDefinition:GetNewContainerName(tieRealm: TieRealm): string
700
814
  end
701
815
  end
702
816
 
703
- function TieDefinition:GetMemberMap()
817
+ function TieDefinition.GetMemberMap<T>(self: TieDefinition<T>)
704
818
  return self._memberMap
705
819
  end
706
820
 
@@ -711,7 +825,7 @@ end
711
825
  @param tieRealm TieRealm? -- Optional tie realm
712
826
  @return boolean
713
827
  ]=]
714
- function TieDefinition:IsImplementation(implParent: Instance, tieRealm: TieRealm?): boolean
828
+ function TieDefinition.IsImplementation<T>(self: TieDefinition<T>, implParent: Instance, tieRealm: TieRealm?): boolean
715
829
  assert(typeof(implParent) == "Instance", "Bad implParent")
716
830
  assert(TieRealmUtils.isTieRealm(tieRealm) or tieRealm == nil, "Bad tieRealm")
717
831
 
@@ -18,6 +18,21 @@ local TieImplementation = setmetatable({}, BaseObject)
18
18
  TieImplementation.ClassName = "TieImplementation"
19
19
  TieImplementation.__index = TieImplementation
20
20
 
21
+ export type TieImplementation<T> =
22
+ typeof(setmetatable(
23
+ {} :: {
24
+ _tieDefinition: any,
25
+ _adornee: Instance,
26
+ _actualSelf: any,
27
+ _implementationTieRealm: TieRealms.TieRealm,
28
+ _implParent: Instance,
29
+ _memberImplementations: { [string]: any },
30
+ _memberMap: { [string]: any },
31
+ },
32
+ {} :: typeof({ __index = TieImplementation })
33
+ ))
34
+ & T
35
+
21
36
  --[=[
22
37
  Constructs a new implementation. Use [TieDefinition.Implement] instead of using this directly.
23
38
 
@@ -26,15 +41,15 @@ TieImplementation.__index = TieImplementation
26
41
  @param implementer table
27
42
  @param implementationTieRealm TieRealm
28
43
  ]=]
29
- function TieImplementation.new(
44
+ function TieImplementation.new<T>(
30
45
  tieDefinition,
31
46
  adornee: Instance,
32
47
  implementer,
33
48
  implementationTieRealm: TieRealms.TieRealm
34
- )
49
+ ): TieImplementation<T>
35
50
  assert(TieRealmUtils.isTieRealm(implementationTieRealm), "Bad implementationTieRealm")
36
51
 
37
- local self = setmetatable(BaseObject.new(), TieImplementation)
52
+ local self: TieImplementation<T> = setmetatable(BaseObject.new() :: any, TieImplementation)
38
53
 
39
54
  self._tieDefinition = assert(tieDefinition, "No definition")
40
55
  self._adornee = assert(adornee, "No adornee")
@@ -56,22 +71,22 @@ function TieImplementation.new(
56
71
  self._maid:DoCleaning()
57
72
 
58
73
  for key, _ in pairs(self) do
59
- rawset(self, key, nil)
74
+ rawset(self :: any, key, nil)
60
75
  end
61
76
  end)
62
77
 
63
78
  return self
64
79
  end
65
80
 
66
- function TieImplementation:GetImplementationTieRealm()
81
+ function TieImplementation.GetImplementationTieRealm<T>(self: TieImplementation<T>): TieRealms.TieRealm
67
82
  return self._implementationTieRealm
68
83
  end
69
84
 
70
- function TieImplementation:GetImplParent()
85
+ function TieImplementation.GetImplParent<T>(self: TieImplementation<T>): Instance
71
86
  return self._implParent
72
87
  end
73
88
 
74
- function TieImplementation:__index(index)
89
+ function TieImplementation.__index<T>(self: TieImplementation<T>, index)
75
90
  if TieImplementation[index] then
76
91
  return TieImplementation[index]
77
92
  end
@@ -85,12 +100,12 @@ function TieImplementation:__index(index)
85
100
  or index == "_memberMap"
86
101
  or index == "_actualSelf"
87
102
  then
88
- return rawget(self, index)
103
+ return rawget(self :: any, index)
89
104
  end
90
105
 
91
- local memberMap = rawget(self, "_memberMap")
106
+ local memberMap = rawget(self :: any, "_memberMap")
92
107
  local memberDefinition = memberMap[index]
93
- local implementationTieRealm = rawget(self, "_implementationTieRealm")
108
+ local implementationTieRealm = rawget(self :: any, "_implementationTieRealm")
94
109
 
95
110
  if memberDefinition then
96
111
  if memberDefinition:IsAllowedForImplementation(self._implementationTieRealm) then
@@ -109,7 +124,7 @@ function TieImplementation:__index(index)
109
124
  end
110
125
  end
111
126
 
112
- function TieImplementation:__newindex(index, value)
127
+ function TieImplementation.__newindex<T>(self: TieImplementation<T>, index, value)
113
128
  if
114
129
  index == "_implParent"
115
130
  or index == "_adornee"
@@ -119,7 +134,7 @@ function TieImplementation:__newindex(index, value)
119
134
  or index == "_memberMap"
120
135
  or index == "_actualSelf"
121
136
  then
122
- rawset(self, index, value)
137
+ rawset(self :: any, index, value)
123
138
  elseif self._memberImplementations[index] then
124
139
  self._memberImplementations[index]:SetImplementation(value, self._actualSelf)
125
140
  elseif TieImplementation[index] then
@@ -129,7 +144,7 @@ function TieImplementation:__newindex(index, value)
129
144
  end
130
145
  end
131
146
 
132
- function TieImplementation:_buildMemberImplementations(implementer)
147
+ function TieImplementation._buildMemberImplementations<T>(self: TieImplementation<T>, implementer)
133
148
  for _, memberDefinition in self._memberMap do
134
149
  local memberName = memberDefinition:GetMemberName()
135
150
  local found = nil
@@ -159,7 +174,7 @@ function TieImplementation:_buildMemberImplementations(implementer)
159
174
  self._implParent.Name = self._tieDefinition:GetNewContainerName(self._implementationTieRealm)
160
175
  end
161
176
 
162
- function TieImplementation:_getErrorMessageForNotAllowedMember(memberDefinition)
177
+ function TieImplementation._getErrorMessageForNotAllowedMember<T>(self: TieImplementation<T>, memberDefinition)
163
178
  local errorMessage = string.format(
164
179
  "[TieImplementation] - Member implements %s only member %s (we are a %s implementation)",
165
180
  memberDefinition:GetMemberTieRealm(),
@@ -182,7 +197,7 @@ function TieImplementation:_getErrorMessageForNotAllowedMember(memberDefinition)
182
197
  return errorMessage
183
198
  end
184
199
 
185
- function TieImplementation:_getErrorMessageRequiredMember(memberDefinition)
200
+ function TieImplementation._getErrorMessageRequiredMember<T>(self: TieImplementation<T>, memberDefinition)
186
201
  local errorMessage = string.format(
187
202
  "[TieImplementation] - Missing %s member %s (we are a %s implementation)",
188
203
  memberDefinition:GetMemberTieRealm(),
@@ -7,16 +7,36 @@
7
7
 
8
8
  local require = require(script.Parent.loader).load(script)
9
9
 
10
+ local Observable = require("Observable")
10
11
  local TieMethodInterfaceUtils = require("TieMethodInterfaceUtils")
11
12
  local TiePropertyInterface = require("TiePropertyInterface")
13
+ local TieRealms = require("TieRealms")
12
14
  local TieSignalInterface = require("TieSignalInterface")
13
15
 
14
16
  local TieInterface = {}
15
17
  TieInterface.ClassName = "TieInterface"
16
18
  TieInterface.__index = TieInterface
17
19
 
18
- function TieInterface.new(definition, implParent: Instance?, adornee: Instance?, interfaceTieRealm)
19
- local self = setmetatable({}, TieInterface)
20
+ export type TieInterface<T> =
21
+ typeof(setmetatable(
22
+ {} :: {
23
+ _definition: any,
24
+ _implParent: Instance?,
25
+ _adornee: Instance?,
26
+ _interfaceTieRealm: string,
27
+ _memberDefinitionMap: { [string]: any },
28
+ },
29
+ {} :: typeof({ __index = TieInterface })
30
+ ))
31
+ & T
32
+
33
+ function TieInterface.new<T>(
34
+ definition,
35
+ implParent: Instance?,
36
+ adornee: Instance?,
37
+ interfaceTieRealm: TieRealms.TieRealm
38
+ ): TieInterface<T>
39
+ local self: TieInterface<T> = setmetatable({} :: any, TieInterface)
20
40
 
21
41
  assert(implParent or adornee, "ImplParent or adornee required")
22
42
 
@@ -34,11 +54,11 @@ end
34
54
 
35
55
  @return boolean
36
56
  ]=]
37
- function TieInterface:IsImplemented(): boolean
38
- local implParent = rawget(self, "_implParent")
39
- local adornee = rawget(self, "_adornee")
40
- local definition = rawget(self, "_definition")
41
- local interfaceTieRealm = rawget(self, "_interfaceTieRealm")
57
+ function TieInterface.IsImplemented<T>(self: TieInterface<T>): boolean
58
+ local implParent = rawget(self :: any, "_implParent")
59
+ local adornee = rawget(self :: any, "_adornee")
60
+ local definition = rawget(self :: any, "_definition")
61
+ local interfaceTieRealm = rawget(self :: any, "_interfaceTieRealm")
42
62
 
43
63
  if implParent then
44
64
  if adornee then
@@ -62,13 +82,13 @@ end
62
82
 
63
83
  @return Instance?
64
84
  ]=]
65
- function TieInterface:GetTieAdornee(): Instance?
66
- local adornee = rawget(self, "_adornee")
85
+ function TieInterface.GetTieAdornee<T>(self: TieInterface<T>): Instance?
86
+ local adornee = rawget(self :: any, "_adornee")
67
87
  if adornee then
68
88
  return adornee
69
89
  end
70
90
 
71
- local implParent = rawget(self, "_implParent")
91
+ local implParent = rawget(self :: any, "_implParent")
72
92
  if implParent then
73
93
  return implParent.Parent
74
94
  end
@@ -81,11 +101,11 @@ end
81
101
 
82
102
  @return Observable<boolean>
83
103
  ]=]
84
- function TieInterface:ObserveIsImplemented()
85
- local implParent = rawget(self, "_implParent")
86
- local adornee = rawget(self, "_adornee")
87
- local definition = rawget(self, "_definition")
88
- local interfaceTieRealm = rawget(self, "_interfaceTieRealm")
104
+ function TieInterface.ObserveIsImplemented<T>(self: TieInterface<T>): Observable.Observable<boolean>
105
+ local implParent = rawget(self :: any, "_implParent")
106
+ local adornee = rawget(self :: any, "_adornee")
107
+ local definition = rawget(self :: any, "_definition")
108
+ local interfaceTieRealm = rawget(self :: any, "_interfaceTieRealm")
89
109
 
90
110
  if implParent then
91
111
  if adornee then
@@ -98,13 +118,13 @@ function TieInterface:ObserveIsImplemented()
98
118
  return definition:ObserveIsImplemented(adornee, interfaceTieRealm)
99
119
  end
100
120
 
101
- function TieInterface:__index(index)
102
- local interfaceTieRealm = rawget(self, "_interfaceTieRealm")
121
+ function TieInterface.__index<T>(self: TieInterface<T>, index)
122
+ local interfaceTieRealm = rawget(self :: any, "_interfaceTieRealm")
103
123
 
104
- local member = (rawget(self, "_memberDefinitionMap") :: any)[index]
105
- local definition = rawget(self, "_definition")
106
- local adornee = rawget(self, "_adornee")
107
- local implParent = rawget(self, "_implParent")
124
+ local member = (rawget(self :: any, "_memberDefinitionMap") :: any)[index]
125
+ local definition = rawget(self :: any, "_definition")
126
+ local adornee = rawget(self :: any, "_adornee")
127
+ local implParent = rawget(self :: any, "_implParent")
108
128
 
109
129
  if member then
110
130
  if member:IsAllowedOnInterface(interfaceTieRealm) then