How do i type property as provided type

I'm making my property implementation and i need to get access to instance's property using just name of it. in roblox studio you can just do Instance[property_name] and it will return property, but how i can do it in ts?
No description
52 Replies
alihsaas
alihsaas3w ago
you have to be more specfic with the typings for connect_to, string is too general
Tverksaac 2.0
Tverksaac 2.0OP3w ago
but then ill need to list every possible property, no?
alihsaas
alihsaas3w ago
do you need every possible property? and you can use the InstanceProperties<T> utility type
Tverksaac 2.0
Tverksaac 2.0OP3w ago
ye i am oh i think it would help
alihsaas
alihsaas3w ago
mhm, just give it the Instance you want the properties for
wAD
wAD3w ago
keyof WriteableInstanceProperties<YourInstance>
Tverksaac 2.0
Tverksaac 2.0OP3w ago
it helped, now it even autofills properties, but how do i add property name to property chaned signal? it still thinks that this instance have only like 4 properties even tho i typed this instance as provided instance
No description
wAD
wAD3w ago
what is the type of this.instance
Tverksaac 2.0
Tverksaac 2.0OP3w ago
No description
Tverksaac 2.0
Tverksaac 2.0OP3w ago
ConnectedInstance is ProvidedInstance extends Instance
Tverksaac 2.0
Tverksaac 2.0OP3w ago
No description
Tverksaac 2.0
Tverksaac 2.0OP3w ago
should i give you full code?
wAD
wAD3w ago
yes
Tverksaac 2.0
Tverksaac 2.0OP3w ago
export interface _SepartaredProperty<T> { readonly name: string; value: T; changed: RBXScriptSignal; Set: (this: SepartaredProperty<T>, value: T) => void; Get: (this: SepartaredProperty<T>) => T; Behaviours: { OnTick: (this: void) => void; OnChanged: (this: void, new_value: T) => void; CanSet: (this: void) => boolean; }; SetBehaviour: ( this: void, behaviour_to_set: "OnTick" | "OnChanged" | "CanSet", new_behaviour: (this: void) => boolean | void, ) => void; } export interface _ConnectedProperty<T, ConnectedInstance extends Instance> extends _SepartaredProperty<T> { instance: ConnectedInstance; connected_to: keyof WritableInstanceProperties<ConnectedInstance>; override: boolean; } export class SepartaredProperty<T> implements _SepartaredProperty<T> { readonly name: string; value: T; changed: RBXScriptSignal<Callback>; SetBehaviour: ( this: void, behaviour_to_set: "OnTick" | "OnChanged" | "CanSet", new_behaviour: (this: void) => boolean | void, ) => void; Behaviours: { OnTick: (this: void) => void; OnChanged: (this: void, new_value: T) => void; CanSet: (this: void) => boolean; }; protected _changed_bind: BindableEvent<Callback>; constructor(name: string, value: T) { this.name = name; this.value = value; this._changed_bind = new Instance("BindableEvent"); this.changed = this._changed_bind.Event; this.SetBehaviour = function () {}; this.Behaviours = { OnTick() {}, OnChanged(new_value) {}, CanSet() { return true; }, }; this.changed.Connect((new_value) => { this.Behaviours.OnChanged(new_value); }); } public Set(set_to: T) { if (this.Behaviours.CanSet()) { if (this.value === set_to) { return true; } this.value = set_to; this._changed_bind.Fire(this.value); return true; } else { return true; } } public Get() { return this.value; } } export class ConnectedProperty<T, ConnectedInstance extends Instance> extends SepartaredProperty<T> implements _SepartaredProperty<T> { instance: ConnectedInstance; connected_to: keyof WritableInstanceProperties<ConnectedInstance>; override: boolean; constructor( Name: string, Value: T, ConnectToInstance: ConnectedInstance, InstancesPropertyName: keyof WritableInstanceProperties<ConnectedInstance>, Override: boolean, ) { super(Name, Value); this.instance = ConnectToInstance; this.connected_to = InstancesPropertyName; this.override = Override; this.changed.Connect((new_value) => { this.instance[InstancesPropertyName] = new_value; }); this.instance.GetPropertyChangedSignal(InstancesPropertyName).Connect(); } } i started learning ts and flamework like yesterday so theres will be alot strange things
Tester
Tester3w ago
this.instance[PropertyName as never] I think will help Esp this.instance[PropertyName as never] = new_value as never
Tverksaac 2.0
Tverksaac 2.0OP3w ago
it looks like it helped thank you!! Is it possible for you to explain why? i dont really understand
No description
wAD
wAD3w ago
playground link please don't never cast this is a bad practice never casting is basically ignoring the type system
Tverksaac 2.0
Tverksaac 2.0OP3w ago
ohhh ok
wAD
wAD3w ago
here's the solution
Tester
Tester3w ago
Fair, as quick fix I think it could work if the type is hard
wAD
wAD3w ago
it couldn't infer RBXObject properly so i helped it a bit by passing it into a generic argument this.instance.GetPropertyChangedSignal<ConnectedInstance>(InstancesPropertyName)
Tverksaac 2.0
Tverksaac 2.0OP3w ago
i see now thank you so much!
Tverksaac 2.0
Tverksaac 2.0OP3w ago
when i try to get instances property value it gives an error. Ts dont count this property as T. How do i type it to be same type as T?
No description
wAD
wAD3w ago
export class ConnectedProperty<
ConnectedInstance extends Instance,
Name extends keyof WritableInstanceProperties<ConnectedInstance>
>
extends SepartaredProperty<ConnectedInstance[Name]>
implements _SepartaredProperty<ConnectedInstance[Name]>
{
instance: ConnectedInstance;
connected_to: keyof WritableInstanceProperties<ConnectedInstance>;
override: boolean;

constructor(
Name: string,
Value: ConnectedInstance[Name],
ConnectToInstance: ConnectedInstance,
InstancesPropertyName: keyof WritableInstanceProperties<ConnectedInstance>,
Override: boolean,
) {
super(Name, Value);

this.instance = ConnectToInstance;
this.connected_to = InstancesPropertyName;
this.override = Override;

this.changed.Connect((new_value) => {
this.instance[InstancesPropertyName] = new_value;
});
this.instance.GetPropertyChangedSignal<ConnectedInstance>(InstancesPropertyName)
}
}
export class ConnectedProperty<
ConnectedInstance extends Instance,
Name extends keyof WritableInstanceProperties<ConnectedInstance>
>
extends SepartaredProperty<ConnectedInstance[Name]>
implements _SepartaredProperty<ConnectedInstance[Name]>
{
instance: ConnectedInstance;
connected_to: keyof WritableInstanceProperties<ConnectedInstance>;
override: boolean;

constructor(
Name: string,
Value: ConnectedInstance[Name],
ConnectToInstance: ConnectedInstance,
InstancesPropertyName: keyof WritableInstanceProperties<ConnectedInstance>,
Override: boolean,
) {
super(Name, Value);

this.instance = ConnectToInstance;
this.connected_to = InstancesPropertyName;
this.override = Override;

this.changed.Connect((new_value) => {
this.instance[InstancesPropertyName] = new_value;
});
this.instance.GetPropertyChangedSignal<ConnectedInstance>(InstancesPropertyName)
}
}
Tverksaac 2.0
Tverksaac 2.0OP3w ago
what does extends SepartaredProperty<ConnectedInstance[Name]> mean? Like why you putting Name in square bruckets?
wAD
wAD3w ago
indexing a type basically Name is the property name and Instance[Name] is the property value
Tverksaac 2.0
Tverksaac 2.0OP3w ago
ooooohhhh i seee thanks youu😊
Tverksaac 2.0
Tverksaac 2.0OP3w ago
ohh it seem like still not working or i did something wrong?
No description
Tverksaac 2.0
Tverksaac 2.0OP3w ago
it gives really long error explanation
Tester
Tester3w ago
Hear me out, when you know it's correct and don't want to bother with solving 1 page type error, prob as never could be in handy 🥲
Tverksaac 2.0
Tverksaac 2.0OP3w ago
i'm making this property implementation first of all to learn typescript, and i want to make it as good as possible using good practises so i can learn better. I want not to fix it, but to understand why it happens. Its really hard to understand what happening in ts rn so im asking others
Tester
Tester3w ago
Oh I see Yeah fair So again, what is this code for? Cause I don't see highlight on the phone Can you send screenshot
Tverksaac 2.0
Tverksaac 2.0OP3w ago
this is my property implementation and code erroring is code trying to get instance's property and set property class's value to it screenshot of what
Tverksaac 2.0
Tverksaac 2.0OP3w ago
No description
Tverksaac 2.0
Tverksaac 2.0OP3w ago
No description
Tester
Tester3w ago
What is the use case?
Tverksaac 2.0
Tverksaac 2.0OP3w ago
like for example you create ConnectedProperty named WalkSpeed and connect it to player's walkspeed and then this property have diffrent behaviours such as CanSet, OnTIck, OnChanged and when this property value changes player's walkspeed will change too or you can create property and have it like class itself in a script
Tester
Tester3w ago
Does it sync between server and client? Or you just want only 1 thing responsible for 1 property? And do you use flamework?
Tverksaac 2.0
Tverksaac 2.0OP3w ago
noo its just an class yes
Tester
Tester3w ago
Prob you don't need it the class wrapper for property? If you need it e.g. for the character, prob it's better to use controller to set and manage the walk speed, charm for observable variables and to add component to the character that will apply the walk speed Or you could go without Flamework component
Tverksaac 2.0
Tverksaac 2.0OP3w ago
But i said already that im making it almost only for learning reasons😭
Tester
Tester3w ago
oki
Tverksaac 2.0
Tverksaac 2.0OP3w ago
thanks you very much for trying to help still!!
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Tverksaac 2.0
Tverksaac 2.0OP3w ago
I know it, but i dont really know how to make so ConnectedInstance[Name] returns right type
alihsaas
alihsaas3w ago
change InstancePropertyName to be Name so InstancePropertyName: Name
Tverksaac 2.0
Tverksaac 2.0OP3w ago
oh omg solution was so easy tysm!!!
alihsaas
alihsaas3w ago
all good do you understand what the solution means?
Tverksaac 2.0
Tverksaac 2.0OP3w ago
yesss, but i dont understand how i didnt came to it
alihsaas
alihsaas3w ago
happens ❤️
Tverksaac 2.0
Tverksaac 2.0OP3w ago
wow, now if you give to new Property value diffrent from value of property you connecting it to it gives you an error, i love ts

Did you find this page helpful?