New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
usePrototypeForDefaults cause issues with repeated fields #498
Comments
Ah shoot, right, we forgot we'll have to make new instances of lists and maps... @Vilsol would you like to take a look at ^? |
So when What's interesting is, what should we do if
|
I've created this proof of concept for “magic” repeated field: /**
* Proof of concept of “magic” repeated field.
*
* message Test {
* uint32 id = 1;
* repeated string tags = 2;
* string last = 3;
* }
*/
interface Test {
id: number;
tags: string[];
last: string;
}
const TestBase: Test = {
id: 0,
tags: null as unknown as string[],
last: '',
};
Object.defineProperty(TestBase, 'tags', {
configurable: false,
get() {
const value: string[] = [];
if (this === TestBase) return value;
Object.defineProperty(this, 'tags', {
enumerable: true,
configurable: true,
writable: true,
value
});
return value;
},
set(value: string[]) {
Object.defineProperty(this, 'tags', {
enumerable: true,
configurable: true,
writable: true,
value
});
}
});
console.log('TestBase', TestBase);
const message = Object.create(TestBase) as Test;
console.log('Empty message', message);
console.log('Empty message keys', Object.keys(message));
message.id = 42;
// tags is populated automatically
message.tags.push('test', 'my', 'tags');
message.last = 'Final';
console.log('Filled message', message);
console.log('TestBase', TestBase); Playground Link: Provided |
Another version of “magic”. With helper functions /**
* Proof of concept of “magic” repeated field.
*
* message Test {
* uint32 id = 1;
* repeated string tags = 2;
* repeated uint32 children = 3;
* }
*
* message Second {
* repeated Test tests = 1;
* }
*/
interface Test {
id: number;
tags: string[];
children: number[];
}
interface Second {
tests: Test[];
}
function materialize<Base>(obj: Base, field: keyof Base, value: unknown[]) {
Object.defineProperty(obj, field, {
enumerable: true,
configurable: true,
writable: true,
value
});
return value;
};
function createRepeatedFields<Base>(Base: Base, ...fields: Array<keyof Base>) {
fields.forEach(field => {
Object.defineProperty(Base, field, {
enumerable: true,
get() {
const value: unknown[] = [];
if (this === Base) return value;
return materialize(this, field, value);
},
set(value: unknown[]) {
materialize(this, field, value);
}
});
});
return Base;
}
const TestBase: Test = createRepeatedFields({ id: 0 } as Test, 'tags', 'children');
const SecondBase: Second = createRepeatedFields({} as Second, 'tests');
console.log('TestBase', TestBase);
console.log('SecondBase', SecondBase);
const test = Object.create(TestBase) as Test;
const second: Second = Object.create(SecondBase);
console.log('Fresh test and keys', test, Object.keys(test));
console.log('Fresh second and keys', second, Object.keys(second));
test.id = 42;
// tags is populated automatically
test.tags.push('test', 'my', 'tags');
// one could assign array directly
test.children = [ 1, 3 ];
console.log('Filled test and keys', test, Object.keys(test));
second.tests.push(test, test);
console.log('Filled second and keys', second, Object.keys(second));
console.log('TestBase still empty', TestBase);
console.log('SecondBase still empty', SecondBase); Playground Link: Provided |
For this proto
the generated code is
and this will push tags into prototype's
tags
field. And, e.g. console.log(message) will show an “empty” object andObject.keys().includes("tags")
will be false.The text was updated successfully, but these errors were encountered: