node.js - Nodejs + Typescript + RedisJSON
მე ახლახან დავიწყე ცოტა პროგრამირების სწავლა nodejs-ით, typescript-ით და redis-ით. სამწუხაროდ, შევხვდი პრობლემას redis-თან დაკავშირებით: მე ვაწესებ ინტერფეისს შენახული მონაცემებისთვის redis-ში. თუმცა, როგორც კი ვწერ ტიპს ცვლელის უკან, redis მინდობებს. ესეც იგივეა, როცა redis-დან იღებ კეისებს: როგორ ვუთხრა Typescript-ს რომელ ტიპის მონაცემებია?
მაგალითი :
async function RedisQuestion() {
const redis = createClient();
interface userLogins {
token: string;
active: boolean;
}
interface myUser {
name: string;
id: string;
logins: userLogins[];
}
const objToStore: myUser = {
name: "Karl Mustermann",
id: "1",
logins: [
{
token: "1234",
active: true
},
{
token: "2345",
active: false
}
]
};
await redis.json.set("key", "$", objToStore);
const redisResult = redis.json.get("key") as myUser;
console.log(redisUser);
}
ის მუშაობს ისე, რომ თუ ვამბობ
await redis.json.set("key", "$", objToStore as any);
და თუ მე მივიღებ მნიშვნელობებს Redis-დან:
await redis.json.get("key") as any as myUser;
მაგრამ უნდა არსებობდეს უკეთესი გზა?! იმედი მაქვს, შეგიძლიათ დამეხმაროთ :)
დიდი მადლობა
პასუხი #1
მოკლე წაკითხვა
RedisJSON ტიპის გამოხატულება ელოდება, რომ მოცემულ JSON ობიექტს ჰქონდეს ინდექსის სიგნატურის გამოხატულება. თქვენი myUser ინტერფეისი ამას არ შეიცავს, ამიტომ ისინი დაუკავშირდებიან.
თქვენ უნდა გამოიყენოთ ტიპი (გადამატებით ამის შესახებ ქვემოთ) ინტერფეისის ნაცვლად, ან მკაფიოდ შეიტანოთ ინდექსის სიგნატურა თქვენს ინტერფეისის გამოხატულებაში.
შემდეგი კოდი მუშაობს:
type UserLogins = {
token: string;
active: boolean;
}
type MyUser = {
name: string;
id: string;
logins: UserLogins[];
}
async function redisQuestion() {
const redis = createClient();
const objToStore: MyUser = {
name: 'Karl Mustermann',
id: '1',
logins: [],
};
await redis.json.set('key', '$', objToStore);
// You can use type assertion here to tell Typescript which type will the GET return.
// You should include the 'null' to force you to check for a null result and prevent
// runtime errors.
const redisUser = await redis.json.get('key') as MyUser | null;
console.log(redisUser);
}
განმარტება
კოდი, რომელიც თქვენ აძლევთ, აყენებს შემდეგ Typescript შეცდომას:
ტიპი 'myUser' არ არის განსაზღვრული ტიპისთვის 'RedisJSONObject'.
ინდექსის სიგნატურა ტიპისთვის 'string' მიკლებულია ტიპში 'myUser'
მეთოდი redis.json.set() ელოდება მესამე პარამეტრს იყოს ტიპურად შესაბამისი RedisJSON-თან, რომელიც განსაზღვრულია ასე:
type RedisJSON = null | boolean | number | string | Date | RedisJSONArray | RedisJSONObject;
interface RedisJSONObject {
[key: string]: RedisJSON;
[key: number]: RedisJSON;
}
ეს [key: string]: RedisJSON; არის ინდექსის სიგნატურის დეკლარაცია.
როდესაც განსაზღვრავთ MyUser-ს როგორც ინტერფეისს, თქვენ მას არასაპროგრამო ხდით RedisJSONObject-თან, რადგან ინტერფეისები არ შეიცავენ ინდექსის დეკლარაციას, თუ თქვენ მას სპეციალურად არ განსაზღვრავთ.
ინტერვეფეისებისა და ტიპების შეცვლა შესაძლებელია Typescript-ში. თუმცა, არსებობს შპრალის განსხვავებები მათ ქმედებაში.
საკვანძო განსხვავებების გარდა, ტიპებში შედის ინდექსის ხელმოწერა ისე, რომ არ იყოს პირდაპირ განსაზღვრული, ხოლო ინტერფეისებს მსგავსი არ აქვთ.
ეს არის იგი, შესაბამისად, ამ შემთხვევაში, MyUser-ის ტიპის განსაზღვრა იცავს შეცდომას.
იმედი მაქვს, ეს ეხმარება!
