Reputation: 36311
I have a class with a Proxy in it which looks like this:
export class Row<T extends ModelItems> {
private _row: T = <T>{}
public constructor(rowItems?: T) {
if (rowItems) { this._row = rowItems }
return new Proxy(this, {
get: function (target, prop) {
return (<any>target)[prop] || target._row[prop] || ''
}
/* set(): snipped */
}
}
When I do this:
interface User {
id: number
first: string
last: string
username: string
}
let row = new Row<User>({/* My object */})
How can I get it so that when I type row
I get a list of items that are defined in the User
interface. Right now all that gets suggested are the actual methods/properties that are in the root of the object.
I have tried this:
export interface Row<T extends ModelItems> {
[key: string]: T
}
This however doesn't seem to help at all other than telling me that my methods aren't defined propertly
Upvotes: 0
Views: 111
Reputation: 328342
It looks like you want an instance of Row<T>
to also be a T
itself; is that right? TypeScript won't let you do something like class Row<T> implements T
, nor will it easily infer that itself. Instead you could do something like the following:
export class _Row<T> {
// ... your definition above
}
// Row type alias
export type Row<T extends ModelItems> = _Row<T> & T;
// Row value alias
export const Row = _Row as {
new <T>(rowItems?: T): Row<T>
prototype: _Row<{}>
}
This behaves more or less the same at runtime, but now TypeScript will understand that an instance of Row<T>
has all the properties that T
has:
declare const u: User;
let row = new Row(u); // inferred as Row<User>
row.username // string
If you are trying to represent something different, like a Row<T>
behaves like something with all the keys of T
but with possibly-empty-string properties, you could replace the // Row type alias
with this instead:
// Row type alias
export type Row<T extends ModelItems> = _Row<T> &
{[K in keyof T]: T[K] | ''};
And verify that it behaves as you expect:
declare const u: User;
let row = new Row(u); // inferred as Row<User>
row.id // number || ''
Hope that helps; good luck!
Upvotes: 2