Trying to develop a TypeScript class where it is initialized with an object and contains a method that only accepts keys from that object. Here's the code:
class MyClass {
properties = {};
constructor(properties) {
this.properties = properties;
}
// Method should only accept keys from this.properties
pick(...propNames) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
Encountered a similar issue as mentioned here, but struggling to apply it in my scenario since the properties are externally passed.
const props = { key: 'value', key2: 'value2' };
interface PropKeys {
key: string;
key2: string;
}
type KeyName = keyof(PropKeys);
// How can I make this work for the class?
const instance = new MyClass(props);
instance.pick('key', 'key2'); // Works fine
instance.pick('key3'); // Should produce a type error
Is there a solution? Can this be accomplished without explicitly defining InstanceKeys
, but by deriving them from the initialize props?
Looking into generics, thinking of something like this:
class MyClass {
properties = {};
constructor<Type>(properties: Type) {
this.properties = properties;
type TypeKeys = keyof(Type);
}
pick(...propNames: TypeKeys[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
However, encountering two type errors:
- On
<Type>
: "Type parameters cannot appear on a constructor declaration." - On
TypeKeys[]
: "Cannot find name 'TypeKeys'. (Out of scope.)"
UPDATE: Getting closer, but facing an issue when properties are initially defined above the constructor:
class MyClass<PropType extends Properties> {
properties: PropType = {};
constructor(properties: PropType) {
this.properties = properties;
}
pick(...propNames: Array<keyof(PropType)>) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
The TS error encountered on that line is
Type '{}' is not assignable to type 'PropType'. '{}' is assignable to the constraint of type 'PropType', but 'PropType' could be instantiated with a different subtype of constraint 'Properties'
The concern here is that any passed-in properties
may have their own keys, but must be instances of type Properties, which limits the values.