class MyStore {
data: Record<string, string> = {};
getKey(key: string, defaultValue?: string): string | undefined {
return this.data[key] ?? defaultValue;
}
}
const store = new MyStore();
const value1 = store.getKey("test");
const value2 = store.getKey("test", "def");
- Now
value1
has type ofstring | undefined
. It is right, no problem there. - But
value2
has also same type ofvalue1
. How to update signature ofgetKey()
so that when default value is provided, there will be noundefined
. Likevalue2
should be of typestring
only.
CodePudding user response:
Easiest way (which also plays nicely with intellisense) is with function overloads:
class MyStore {
data: Record<string, string> = {};
getKey(key: string): string | undefined
getKey(key: string, defaultValue: string): string
getKey(key: string, defaultValue?: string): string | undefined {
return this.data[key] ?? defaultValue;
}
}
You could also work this out with generics for a considerably less readable solution:
class MyStore {
data: Record<string, string> = {};
getKey<T extends string | undefined>(key: string, defaultValue?: T):
T extends string ? string : string | undefined {
return this.data[key] ?? defaultValue;
}
}
CodePudding user response:
Using a generic should work but your return value should not contain string anyway. Since, your Record
s values are of type any
.
getKey<T = undefined>(key: string, defaultValue?: T): string | T {
return this.data[key] ?? defaultValue;
}
If you are planning on using only strings for the values. I suggest updating the type of the record.
data: Record<string, string> = {};