Reputation: 669
const log = {
counter: {
a: 1,
b: 2,
c: 3,
},
increment(entry: keyof typeof this.counter){
this.counter[entry]++;
}
};
function incrementLog(entry:keyof typeof log.counter){
log.counter[entry]++;
}
incrementLog('a'); // ok
incrementLog('d'); // error, must be 'a' | 'b' | 'c'
log.increment('a'); // ok
log.increment('d'); // no error
I want to enforce the argument type of increment
method to be keyof typeof log.counter
, which is 'a' | 'b' | 'c'
. I can achieve it in the standalone function, but it doesn't work in the increment
method: 'this' is not defined.
I've also tried log.counter
instead of this.counter
on the method definition, but that creates a 'circular initializer' which also doesn't work as intended.
I hope not to manually type the log
or manually type the counter
, because when I make changes to the object, I hope to only make changes in one place.
Upvotes: 2
Views: 464
Reputation: 36
They fixed it.
P.S.: I have to write this to go over the minimum thirty characters.
Upvotes: 0
Reputation: 26627
Define counter
before log
. You cannot reference type in the middle of expression which defines the type. You can easily avoid duplicating definition/initialization.
const counter = {
a: 1,
b: 2,
c: 3,
};
const log = {
counter,
increment(entry: keyof typeof counter){
this.counter[entry]++;
}
};
function incrementLog(entry:keyof typeof log.counter){
log.counter[entry]++;
}
incrementLog('a'); // ok
incrementLog('d'); // error, must be 'a' | 'b' | 'c'
log.increment('a'); // ok
log.increment('d'); // error, must be 'a' | 'b' | 'c'
Upvotes: 2
Reputation: 51816
When writing object-oriented code in TypeScript, it's a lot easier to use class syntax than it is to force things to work with plain object literals:
class Log {
counter = {
a: 1,
b: 2,
c: 3
};
increment(entry: keyof Log['counter']) {
this.counter[entry]++;
}
}
const log = new Log();
function incrementLog(entry:keyof Log['counter']) {
log.counter[entry]++;
}
incrementLog('a'); // ok
incrementLog('d'); // error
log.increment('a'); // ok
log.increment('d'); // error
Upvotes: 2
Reputation: 97
You should create a type or interface for log
:
interface Log<T extends {[key: string]: number}> {
counter: T;
increment(element: keyof T): void;
}
Upvotes: 0