JSON ობიექტის კონვერტირება ინტერფეისში TypeScript-ში აღემატება გრაფემთა მგრძნობიარობას
არის რაიმე გზა, რომ jsonObj-ი გადაგვიყვანოთ რომელიმე ინტერფეისში, როცა json-ის ზოგი წევრი განსხვავდება ინტერფეისის წევრებისგან მხოლოდ ასოებზე დამოკიდებულებით?
interface Desire {
propTest1: string,
propTest2: string
}
let jsonFromApi = {
PropTest1: "aa",
PropTest2: "bb"
}
let result = smartCast<Desire>(jsonFromApi);
console.log(results)
// I expect {
propTest1: "aa",
propTest2: "bb"
}
და ეს ისაა, რაც მე აქამდე ვცადე:
function smartCast<T>(from: object): T{
type LOWERCASE = { [p in keyof T & string as Lowercase<`${p}`>]: T[p] }
type LOWERCASE_MAP = { [p in keyof T & string as Lowercase<`${p}`>]: p }
const lowerCase = Object.entries(from).reduce((a: any, [key, val]) => {
a[key.toLowerCase()] = val;
return a;
}, {}) as LOWERCASE;
console.log("lowercase ", lowerCase)
const lowerCaseMap = Object.entries(lowerCase).reduce((a: any, [key, val]) => {
a[key] = key;// how to get something like LOWERCASE_MAP[key] ?? typescript === runtime without types :(((
return a;
}, {});
return Object.entries(lowerCase).reduce((a: any, [key, val]) => {
a[lowerCaseMap[key]] = val
}, {}) as T;
}
პასუხი #1
შენ გინდა შეცვალო JSON ობიექტის თვისებების ასოები, რომელიც იღებ API-დან რანთაიმში. მაგრამ სად არის TypeScript-ის განსაზღვრები ობიექტებისთვის, რომლებიც პირველად მოდის? JSON-ის პარსინგი ჩვეულებრივ შენ მისცემს any ტიპს დიზაინ დროში, თუ არ იყენებ API ბიბლიოთეკას, რომელიც უკვე აბრუნებს ტიპის მქონე ობიექტებს.
თუ თქვენ გაქვთ ტიპის განსაზღვრებები ან თქვენ მაინც მექანიკურად აპირებთ მათი ხელახლა შექმნას, უბრალოდ დააყენეთ თქვენი შემთხვევის გამრეკველი ფუნქციის დაბრუნების ტიპი ამ ტიპზე. იმისათვის, რომ გამოიყენოთ TypeScript-ის გენერიკები, ამის გაკეთება საჭირო არ არის:
type AnyObject = {[index: string]: unknown};
interface DesiredResultObject {
prop1: string;
prop2: number;
}
const jsonObject = {
Prop1: "answer",
Prop2: 42,
}
function toLowerCaseProps(obj: AnyObject): DesiredResultObject {
return Object.entries(obj).reduce((a, [key, val]) => {
a[key.toLowerCase()] = val;
return a;
}, {} as AnyObject) as unknown as DesiredResultObject;
}
const result = toLowerCaseProps(jsonObject);
თუ თქვენ უკვე გაქვთ API ობიექტებისთვის ტიპების განსაზღვრები და გინდათ მათ გასაღებების გარდაქმნა, მაგრამ არ გინდათ ახალი ტიპის შექმნა ხელით, შეგიძლიათ გააკეთოთ რაღაც მსგავსი:
type AnyObject = {[index: string]: unknown};
type LowerCaseProps<T extends AnyObject> = {
[K in keyof T as Lowercase<string & K>]: T[K]
};
const jsonObject = {
Prop1: "answer",
Prop2: 42
}
function toLowerCaseProps<T extends AnyObject>(obj: T): LowerCaseProps<T> {
return Object.entries(obj).reduce((a, [key, val]) => {
a[key.toLowerCase()] = val;
return a;
}, {} as AnyObject) as LowerCaseProps<T>;
}
const result = toLowerCaseProps(jsonObject);
console.log(result.prop1); // outputs "answer"
// console.log(result.Prop1); // this won't compile
console.log(result.prop2); // outputs 42
// console.log(result.Prop2); // this won't compile
