P extends {x: any}
in this scenario, you are indicating to accept any extended object of type {x:any}
You should specify One
and Two
classes for reporting purposes
interface Base {x:any}
interface One extends Base {
y?:string
}
interface Two extends Base {
z?:string
}
const numberStringConverter = <T extends string | number,P extends Base >(p: P): T => {
if(typeof p.x === 'string'){
return Number(p.x) as T
}
if(typeof p.x === 'number'){
return String(p.x) as T
}
return p.x as T;
}
numberStringConverter<string,One>({x:1});
numberStringConverter<string,Two>({x:1});
If only one class is accepted, avoid using extends and directly pass the class as a parameter
const numberStringConverter2 = <T extends string | number,>(p: Base): T => {
if(typeof p.x === 'string'){
return Number(p.x) as T
}
if(typeof p.x === 'number'){
return String(p.x) as T
}
return p.x as T;
}
You can also utilize it differently. If Generic
does not have a specified type, it defaults to any
.
const numberStringConverter = <T extends string | number,P extends {x: any}=any>(p: P): T => {
if(typeof p.x === 'string'){
return Number(p.x) as T
}
if(typeof p.x === 'number'){
return String(p.x) as T
}
return p.x as T;
}
numberStringConverter<string>({x:1});
numberStringConverter<string>({x:1});
// The issue with this approach is that the ts compiler won't flag an error here
//and the p.x line in the function will cause an error at runtime
// has to be identified during runtime
numberStringConverter<string>(5);
However, I believe this method suits your requirements best.
interface Base { x:any}
const numberStringConverter = <T extends string | number,P extends Base =Base>(p: P): T => {
if(typeof p.x === 'string'){
return Number(p.x) as T
}
if(typeof p.x === 'number'){
return String(p.x) as T
}
return p.x as T;
}
numberStringConverter<string>({x:1});
numberStringConverter<string>({x:1});
// ts compiler will show error
numberStringConverter<string>(5);
P extends Base =Base
where you define that this type is the default unless a specific generic type is provided.