Spread parameters
bennypowers opened this issue · 9 comments
As far as I could tell there's no schema to identify a spread parameter:
custom-elements-manifest/schema.d.ts
Lines 542 to 547 in e527701
custom-elements-manifest/schema.d.ts
Lines 442 to 458 in e527701
This could be useful for class methods or functions that take a spread:
protected notify(...keys: (keyof this)[]): void {
this[update](Object.fromEntries(keys.map(x => [x, this[x]])));
}
For all intents and purposes this would just be:
"parameters": [
{
"name": "keys",
"type": {
"text": "(keyof this)[]"
}
}
]
Right?
this.notify(['a','b','c']);
this.notify(...['a','b','c']);
this.notify('a','b','c');
they're spec'd out as different things, if i'm reading it right:
But these would all be internally handled as being an array, right? No matter how the method is called (or how its specced), the method expects the argument to be an array. Im not sure what value we could add here
it's an array in the function body, but a spread at the call site
so, if the user followed the documentation as you defined it, they would
this.notify(['a','b','c']);
but that would break because keys.map(x => [x, this[x]]
would evaluate to
[
[
['a','b','c'],
/* not something you'd usually index `this` with*/
this[['a','b','c']]
]
]
instead of the intended:
[
['a', this.a],
['b', this.b],
['c', this.c]
]
this.notify(['a','b','c']);
Thats a fair point. How would this look like in the schema, though?
Maybe:
"parameters": [
{
"name": "keys",
"spread": true,
"type": {
"text": "(keyof this)[]"
}
}
]
?
off the top
notify(a, ...keys, b) {}
"parameters": [
{ "name": "a" },
{
"name": "keys",
"rest": true
},
{ "name": "b" }
]
yeah, 🚲
i'd usually reach for an enum rather than a spread, maybe
"kind": "rest"
declare module 'schema' {
export type Parameter {
kind?: "rest"|"spread"
}
}
We should do this, but I think a simple boolean like rest?: true
would probably suffice. There's no other value on the single vs rest axis to represent. spread
isn't a kind of parameter, it's an operation you can use for arguments, but we don't document calls/arguments. rest?: true
goes alone with optional?: true
that we have now.