עוד לא מצאתי איך הדפדפן אמור להצליח לגשת לאתר עם הכתובת http://pizzaluigi
אני חושש שאולי זה יעבוד רק עם תתקין את המכונה עם ה-exe שלהם
yossiz
-
בעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2 -
מערכת לניהול תורמים יעבוד גם עם אתר?@יגעתי-ומצאתי יש תחליף חינמי ל-airtable בשם nocodb
-
בעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2אגב, בסוף הדרך הכי טובה שמצאתי להריץ את המכונה על מק הוא ככה:
sudo qemu-system-x86_64 \ -hda "ubuntuvm-disk001.qcow2" \ -m 2048 \ -smp 4 \ -netdev vmnet-bridged,id=net0,ifname=en0 \ -device virtio-net,netdev=net0 \ -usb -device usb-tablet \ -cpu max \ -rtc base=utcבצורה זו המכונה נמצא ברשת המקומית כעוד מחשב, הוא מקבל כתובת IP מהראוטר ברשת המקומית ואפשר לגשת ל-IP הזה לכל הפורטים הפתוחים
(אין עוד פורטים מעניינים במכונה זו, אין שום דבר מעניין. אולי היטוריית שורת הפקודה בקושי...) -
בעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2@צבי-ש יש לי חדשות טובות בשבילך
אתה יכול להיפטר מהמכונה השמנה
באמת לא מובן מה חשבו. למה צריך פיירפוקס, ליברהאופיס, וכו' כדי להריץ אתר
היה קל מאוד להגיע לדסקטופ
צריך פשוט לתפוס אותו לפני שהוא ננעל
זה מוגדר לנעול אחרי שניה אחת של חוסר פעילות
אבל אפשר לפתוח טרמינל
אחרי שהיה לי טרמינל דיפדפתי בהיסטוריה (כן, יש שם הרבה דברים משעשעים
) וראיתי את הפקודה של gsettingsשמגדיר את ה-idle timeout לנעילה, ופשוט הרצתי במקום זהgsettings reset ...כדי לחזור לברירת המחדלgettings reset org.gnome.desktop.session idle-delay gettings reset org.gnome.desktop.screensaver lock-delayמשם היה קל מאוד להגיע לסיסמת המשתמש (
cecadmin2020) - זה היה גלוי בהיסטוריה של שורת הפקודה - אפשר ככה לקבלsudo(אבל אין שום צורך...)
בדקתי את היסטורית הדפדפן והגעתי לריפו זה
https://github.com/DaniRubin/pizzaCyber
שם יש כל מה שצריך להריץ את האתר...
אאל"ט תוכל להריץ לוקלית על מק בלי להסתבך עם מכונה וירטואלית ענקית
אולי כדאי לא לקרוא את קוד המקור של האתר כדי שזה לא יהרוס לך את הכיף של מציאת החולשות
-
בעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2אגב, זה קצת בושה שלא יכלו להקים מכונה וירטואלית פחות שמן... למה צריך סביבת דסקטופ שלם עבור מכונה שבעיקרון רץ headless
מקווה שחוסר מקצועיות זה לא משקף את רמת כל הקורסאולי תוכל לעשות חסד לקהילה ולהמיר את זה לתמונת דוקר ששוקל 5% מתמונת ה-vbox
-
בעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2@צבי-ש כתב בבעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2:
תוכל להרחיב קצת בהסבר מה בעצם שינת?
לצערי לא אוכל להרחיב כי אני לא מבין לגמרי מה עשיתי... הסתכלתי קצת בתיעוד על תצורות רשת והיה לי השערה שתצורה זו תעבוד אז העתקתי שורת פקודה מדוגמה...
@צבי-ש כתב בבעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2:
וכן אם אני רוצה בכל זאת להשתמש בדומיין http://pizzaluigi/ , אני אצטרך לעשות את זה ברמת הdns אצלי במחשב
אפשר להוסיף לקובץ ההוסטס שpizzaluigi נמצא ב-127.0.0.1
אני לא יודע באיזה מנגנון השתמשו במכונה המקורית כדי לפרסם את שם המכונה שלהם (אולי משהו כמו WINS, אני לא לגמרי מבין בזה)
הבנתי מהתיעוד שאם תרצה גישה מלאה לכל הפורטים, תצטרך תצורת TUN אבל נראה שזה מצריך קצת עבודה להקים
-
בעיה בגישה לדומיין מקומי במכונה וירטואלית על MacBook M2@צבי-ש
זה עבד לי:qemu-system-x86_64 \ -hda "ubuntuvm-disk001.qcow2" \ -m 2048 \ -smp 4 \ -device e1000,netdev=net0 \ -netdev user,id=net0,hostfwd=tcp::8080-:80 \ -vga std \ -usb -device usb-tablet \ -cpu max \ -rtc base=utcואז אפשר להיכנס ב-localhost:8080
שים לב שזה חושף רק פורט 8080 מהאורח, וייתכן שמתישהו בקורס תצטרך לגשת לעוד פורטים
-
מערכת לניהול תורמים יעבוד גם עם אתר?@יגעתי-ומצאתי חפש בפורום, יש כמה נושאים פה על הנושא
אבל זה רלוונטי אחרי שכבר השקעת במסד של אקסס
אם עוד לא השקעת באקסס, לענ"ד אל תבנה מראש עם אקסס אם אתה רוצה לחבר אליו אתר. אקסס לא מיועד לזה.הDB שלי הוא גוגל שיטס
המילים צורמים קצת... שיטס לא מיועד לזה. יש מוצרים אחרים יותר מתאימים
מה שלא כ"כ מאפשר לי להתנהל עם תורמים ומתרימים ועוד ועוד כל מיני
לא הבנתי בדיוק הכוונה, אבל בכל מקרה אני לא חושב שאקסס יהיה הכיוון הנכון לפתור את זה במקרה שלך
תלך יותר לכיוון של DB קלאסי, או כלים כמו airtable
-
תוסף או סקריפט שיכולים לומר לי מה כבר ראיתי ומה עדיין לא@THMV כתב בתוסף או סקריפט שיכולים לומר לי מה כבר ראיתי ומה עדיין לא:
מדובר על האתר הזה
גם שורה זו "מוציא אותי מהכלים..."
@THMV תבדוק בהיסטוריית הפוסטים שלי, אני אדם מתון בד"כ
אבל נראה לי שלא קלטת שמאחורי הניקים בפורום יושבים בני אדם איכפתיים
לא מדובר ברובוטים שמקבלים שאלות דרך העיניים ופולטים תשובות דרך הפהזה לא מקובל כלל לבקש משהו מאנשים בלי להסביר את הפרטים הבסיסיים ביותר
לא חשבת לרגע שאולי הפרט השולי של איזה אתר מדובר יכול לעזור משהו פה?הדבקה של קיר טקסט מהעוזר האישי (בינה מלאכותית) שלך גם הפריע לי
אם יש לך עוזר אישי כל כך נחמד שמוכן לעזור לך, תבקש ממנו באמת לעזור לך,
הרי הוא "כאן לעזור!"
קיבלתי את הרושם שאתה אומר
"אין לי מושג איך עושים X
אבל אתם מתים לעזור לי הרי
אז הנה תשובה של העוזר האחר שלי
תפענח אותו ותביא לי את זה בחתיכות שאני יכול לבלוע"כללו של דבר, תנסה לחשוב על האנשים שמאחורי הניקים, הם איכפתיים ורוצים להיות חברים, תעשה להם חיים יותר קלים
-
צלילה לעומק TS: טייפ X לא זהה ל-union של כל הערכים האפשריים שהטייפ כוללבפוסט הזה אולי לא נתקדם הלאה כי אני רוצה להבהיר כמה נקודות ולחזור על חלק מהמושגים מהפוסט הקודם
הודעות
א. תודה לכל מי שטרח להשאיר לי משוב, אם בצורת הצבעה על הפוסט ואם בערוצים פרטיים (כמה חברים כתבו אלי בערוצים אחרים), אני מעריך את זה!
ב. לכל מי שהתקשה להבין את הפוסט הקודם:
אל תאשים את עצמך. זה לא היה פוסט קל להבנה! כתבתי דברים בקיצור, ולפעמים השמטתי לגמרי הסברים נחוצים.
הנושא עצמו מאוד תיאורטי, וגם הדוגמאות לא היו ממש מעשיות.
אני מתנצל. (אנסה להבא להביא דוגמאות יותר מעשיות)
ולמי שלא התקשה כלל: או שיש לך הכירות קודמת עם הנושא, או שאתה מוכשר, או שלא הבנת באמת
ג. חשוב להבהיר! אין שום צורך להכיר את כל התוכן התיאורטי שכתבתי כדי לקבל תועלת מ-TS. גם אם הנושא לא מושך אותך או אפילו דוחה אותך, אני עדיין ממליץ בחום להשתמש ב-TS כי אפשר לקבל רוב התועלת בלי להבין את הרקע התיאורטי. הפוסט שלי חשוב למי שרוצה ליצור טייפים. רוב הזמן אתה צורך טייפים שאחרים כתבו ולא יוצר טייפים חדשים. וגם רוב הטייפים שתיצור יהיו פשוטים בלי צורך בידע תיאורטי עמוק.
ד. העירו לי על כמה דברים שלא הסברתי די הצורך בפוסט הקודם ואנסה להבהיר אותם כאןמה זה טייפ?
(הרחבה של הקטע "מה זה טייפ" בפוסט הקודם)
התפקיד של טייפים בשפות תכנות זהה לכל השפות: בהנתן ערך כלשהו, המתכנת רוצה לדעת בצורה סטטית (כלומר, בלי להריץ את התוכנה בפועל) איזה פעולות זמינים לו על ערך זה, איך מותר להשתמש בערך.
אבל יש הבדל מהותי בין ההתעסקות עם טייפים בשפות סטטיות (statically typed) "קלאסיות" (JAVA, C++, C#, etc) לטייפים ב-TS
כי בשפות קלאסיות אין עיסוק ישיר עם טייפים עצמם. עוסקים עם קלאסים, שהם "תבניות" או "אב טיפוס" לערכים, קלאס מגדיר איזה שדות הערך חייב להכיל, ובאיזה פעולות הוא צריך לתמוך. וכתוצאה נוצר "טייפ" (שהוא הסט של כל הערכים האפשריים שמתאימים לתבנית) אבל אין עיסוק ישיר עם טייפים עצמם
ב-TS יש עיסוק ישיר עם טייפים עצמם. מחברים טייפים אחד לשני, מחסרים טייפים אחד מהשני, בונים טייפים מטייפים אחרים, דברים שלא קיימים בשפות קלאסיות.
בשפה קלאסית אין מושג של literal type (הטייפ של ערך literal, סט בעל ערך יחיד). כי כל טייפ הוא תוצאה מהצהרה של קלאס שהוא תבנית להרבה ערכים כי העיקר של הטייפ הוא הפעולות שזמינים עליו.
לא כן ב-TS שאפשר לעסוק ישירות עם המושג טייפ.
לכן חשוב לחשוב על טייפים ב-TS כסטים, במקום כתבניות כמו בשפות קלאסיותGENERICS
הדוגמה שהבאתי בפוסט הקודם לא היה מספיק ברור וגם לא כל כך מעשי
אביא דוגמה מעשי ביותר
נגיד שאתה בונה קליינט ל-API
אתה יודע שה-API המדובר תמיד מחזיר תשובות בתבנית זה:type ApiResponse = { success: boolean data: object | undefined error: string | undefined }השימוש ככה:
type User = { ... } type Transaction = { ... } class ApiClient { // users getUserById(id: number): ApiResponse { ... } updateUser(newUser: User): ApiResponse { ... } // transactions listTransactions(userId: number): ApiResponse { ... } // ... } const apiClient = new ApiClient const res: ApiResponse = apiClient.getUserById(id) if (res.success) { const user = res.data // do something with user } else { console.error(error) }הבעיה בקוד הזה הוא שבשורה 18, הדבר היחיד ש-TS יודע על המשתנה
userהוא שזה מסוגobjectאבל הוא לא יודע איזה סוג אובייקט.
דרך אחת לטפל בזה הוא להצהיר על טייפ בשםUserApiResponseושם להצהיר על הטייפ המלא של שדהdata
הבעיה היא שצריך לחזור שוב ושוב על הצהרה זו לכל סוג שלXXXApiResponse
אפשרות אחרת הוא להצהיר שהטייפ שלres.dataהואUserconst user = res.data as Userאבל בצורה זו מאבדים את הבטחת האבטחה של TS וצריך לסמוך על המתכנת שהצהיר נכון על הטייפ
הפתרון הוא להשתמש ב-generic שהוא "טייפ בונה טייפים"
ככה:type ApiResponse<T> = { success: boolean data: T | undefined error: string | undefined } type User = { ... } type Transaction = { ... } class ApiClient { // users getUserById(id: number): ApiResponse<User> { ... } updateUser(newUser: User): ApiResponse<User> { ... } // transactions listTransactions(userId: number): ApiResponse<Transaction[]> { ... } // ... } const apiClient = new ApiClient const res: ApiResponse = apiClient.getUserById(id) if (res.success) { const user = res.data // user is type User } else { console.error(error) }בפסאודו קוד ההצהרה דומה לקוד כזה:
const ApiResponse = function(T: type): type { return new Type(`{ success: boolean data: ${T} | undefined error: string | undefined }`) }תנאים
יש כמה בעיות בדוגמה שהבאתי למעלה עבור שימוש בתנאי
א. זה לא כל כך מעשי
ב. יש באג (הטייפ לא עושה מה שהתכוונתי שהוא יעשה - אולי אכתוב על זה בפוסט אחר) ואין לי ממש דרך לפתור את הבאג
ג. השתמשתי בתחביר שלא הצגתי מקודם (אינדוקס)אני רוצה להביא דוגמה מעשית פשוטה שבונה על הדוגמה הקודמת
נגיד שה-API מחזיר לפעמים אובייקט יחיד ולפעמים מערך
אם הוא מחזיר מערך אז יש שדות נוספות בתשובה
אולי נגיד שדהcountשמחזיר כמה אובייקטים יש בסה"כ
איך נגדיר type כזה?type BaseApiResponse<T> = { success: boolean data: T | undefined error: string | undefined } type ApiResponse<T> = T extends any[] ? BaseApiResponse<T> & { count: number } : BaseApiResponse<T>אפשר לתרגם את זה לקוד פסאודו זה:
function ApiResponse(T: type): type { const base = `{ success: boolean data: ${T} | undefined error: string | undefined }` if (T instanceof Array(any)) { return `base & { count: number }` } else { return base } }Mapped Types
הבאנו למעלה דוגמה שהיא גם מסובכת מדי וגם לא כל כך מעשי לשימוש יומיומי
אני רוצה להביא דוגמה נורמלית מתוך הטייפים המובנים (TS מגיע עם "ספרייה סטנדרטית" של טייפים מובנים)
נבנה על הדוגמה הקודמת שלנו של קליינט API
אז אתה רוצה להגדיר שהפונקציהupdateUserמקבל אובייקט מסוגUserאבל בשונה מ-User, כל השדות הם אופציונליות. (כי מי שרוצה לעדכן רק שדה אחת לא צריך לשלוח את כל השדות)אז אפשר לכתוב טייפ חדש
type User = { name: string foo: string bar: number } type UserUpdate = { name?: string foo?: string bar?: number }אבל זה בזבוז נייר דיו וביטים, וכמובן זה לא DRY מה שאמור לזעזע כל מתכנת ששוה משהו
הפתרון הוא:
updateUser(newUser: Partial<User>): ApiResponse<User> { ... }השתמשנו ב-helper (כך נקראים "פקונציות" אלו שעוזרים לבניית טייפים מבוססים טייפים קיימים) בשם
Partialשלוקח טייפ ומחזיר טייפ עם אותם שדות, רק שכולם נהיים אופציונליים
איך עובד ה-helper הזה?
נסתכל בקוד המקור:type Partial<T> = { [P in keyof T]?: T[P] | undefined; }מילת המפתח
inעובד ככה: עבור כל חבר ב-union שצד הימני מייצג, הוא מריץ את הביטוי שאחרי הנקדותיים כאשר המשתנהPמייצג את החבר הזה מה-unionשימו לב לתחביר שלא הצגנו מקודם:
T[P]- זה אינדוקס בטייפ שעובד בדיוק כמו אינדוקס אובייקט רגיל.T[P]הוא הטייפ של שדהPבתוך טייפTנתרגם את זה לפסאודו קוד:
function keyOf(o: object): union { return new Union(Object.keys(o)) } function Partial(T: type): type { const res = {} for (const P in keyOf(T)) { res[P] = T[P] | undefined } return res }(סליחה. בפסאודו קוד הזה השתמשתי במוסכמות אחרות מהקטעים הקודמים. בקודמים יצרתי טייפ על ידי העברת מחרוזת ל"בנאי של הטייפ" - כביכול. הפעם לשם נוחות התייחסתי לטייפ כאובייקט. זה רק פסאודו קוד כמובן ואני מקווה שהכוונה ברורה)
-
תוסף או סקריפט שיכולים לומר לי מה כבר ראיתי ומה עדיין לא -
תוסף או סקריפט שיכולים לומר לי מה כבר ראיתי ומה עדיין לא@צדיק-תמים כתב בתוסף או סקריפט שיכולים לומר לי מה כבר ראיתי ומה עדיין לא:
קח את הכתובת של האתר המדובר, ותוסיף /feed בסוף הכתובת
יש גם את זה שחלק מהאתרים מממשים
https://blog.whatwg.org/feed-autodiscovery -
תוסף או סקריפט שיכולים לומר לי מה כבר ראיתי ומה עדיין לאיימח שמו של הבינה המלאכותית
ולו רק מפני שהוא מעורר בי נטיות אלימות כלפיו...במחשבה שנייה, זו לא בעיה שלו, הוא כלי, הבעיה במשתמשים בו...
-
צלילה לעומק TS: טייפ X לא זהה ל-union של כל הערכים האפשריים שהטייפ כוללבפוסט זה אני הולך לשתף דבר שלמדתי לאחרונה ב-TS שהיה חידוש עבורי
אני משתמש בנושא זה כקרש קפיצה לכתוב מבוא כללי ל-TS. כדי להסביר את החידוש שגיליתי, אסביר בצורה מתומצתת את המושגים שצריכים להכיר כדי להבין את החידוש
(אם מישהו יתחיל להשתמש בשפה בזכותי והיה זה שכרי. פשוט חבל שיש כל כך הרבה מתכנתים מוכשרים בקהילה שלנו שלא משתמשים ב-TS מחוסר היכרות...)מכיון שאני כותב את הפוסט בהמשכים אשמח אם התגובות יהיו בנושא נפרד
התוכנית:
- קורס מזורז ב-TS
- קטעי הקוד המוקשים לכאורה
- התשובה
מקווה שיהיה קל לקריאה ולתועלת
ובכן, אעביר אותך קורס מזורז מאוד ב-TS:
מה זה טייפ
דרך אחת להסתכל על טייפ הוא ככה:
טייפ הוא סט (set - כן, ההוא מתורת הקבוצות...) של ערכים.
לדוגמה:- הטייפ
numberמייצג את הסט שכולל בתוכו את כל המספרים - הטייפ
1מייצג סט שכולל בתוכו ערך אחד: המספר 1, כמו"כ כל ערך ב-JS הוא גם שם של טייפ שכולל חבר אחד - הערך הזה בעצמו - הטייפ
{ foo: string; bar: number }מייצג את הסט שמכיל כל האובייקטים האפשריים שמכילים שדהfooמסוגstringושדהbarמסוגnumber - הטייפ
neverמייצג סט ריק. סט בלי חברים. - הטייפ
unknownמייצג את הסט של כל הערכים האפשריים. "סט סטי הסטים". הסט הכי גדול ביקום הטייפים. לכן אין הרבה מה לעשות עם ערך מסוג unknown כי אתה לא יודע איזה פעולות מותרים לעשות איתו.
דרך נוספת לחשוב על טייפים:
הטייפ של הערך אומר לנו איזה פעולות מותרות על הערך
למשל:- הטייפ
numberאומר לנו שמותר לעשות פעולת חיבור וחיסור על ערך זה עם מספרים אחרים - הטייפ
stringאומר לנו שמותר לנו לקרוא לפונקציה בשםstartsWithעל הערך שלנו
וכן הלאה
זו גם דרך נכונה לחשוב על טייפים.
בהמשך המאמר נתמקד יותר בפן הראשון: טייפ של ערך מייצג חברות בסט של ערכים.מתמטיקה עם טייפים:
TS נותן שני כלים אריתמטיים לבניית טייפים מורכבים מטייפים אחרים:
חיבור - UNION
האופרטור
|ב-TS עושה את פעולת החיבור באריתמטיקה של טייפים
למשל:- טייפ
1 | 2מייצג חיבור של שני הסטים1ו-2. התוצאה היא סט (טייפ) שכולל שני חברים, 1 ו-2 string | numberמחבר את שני הסטים והתוצאה היא סט גדול שכולל בתוכו כל המחרוזות האפשריים וכל המספרים האפשריים- חיבור עם
never(להזכירכם: זהו הסט עם 0 חברים) הוא כמו פעולת חיבור מספרי של מספר כלשהו עם 0. הפעולה לא משנה את הערך המקורי.
חיסור - INTERSECTION
למדנו איך להרחיב סט עם אופרטור
|עכשיו נלמוד איך להצר סט עם אופרטור&.
האופרטור&מקבל שני סטים משני צידי האופרטור ומחזיר את הסט שכולל רק את החברים בשני הסטים גם יחד
למשל:{ foo: string } & { bar:number }לוקח את הסט שכולל כל האובייקטים האפשריים שיש להם שדהfooמסוג string, וכן את הסט שכולל כל האובייקטים האפשריים שיש להם שדהbarמסוג number, והוא מחזיר סט של כל האובייקטים האפשריים שחברים בשתי הקבוצות: דהיינו אובייקטים שיש להם גם שדה foo וגם שדה bar- פעולת
& unknownלא עושה כלום כי כל ערך אפשרי נמצא בתוך סט ה-unknown
תכנות עם טייפים
TS נותן כלים יותר משוכללים לבניית טייפים על ידי "תכנות"
פונקציות - GENERICS
תחביר ה-generics מקביל לפונקציה המוכרת מתכנות רגיל.
אבל בעוד שפונציקה רגילה פועלת על ערכים, ה-generic פועל על טייפים.
זה פונקציה שמקבל כארגומנט טייפ, ופולט את הטייפ הסופי לפי הלוגיקה של ה-body של הפונקציה.
לדוגמה:- פונקציה שמקבל נוסח תפילה ופולט את הטייפ של היהודי עם נוסח תפילה זו:
// הצהרת טייפ שכולל כל נוסחאות התפילה האפשריים type Nusach = 'Ashkenaz' | 'Sefarad' | 'Edot Hamizrach' // הצהרת טייפ גנרי שמקבל נוסח תפילה ומחזיר טייפ של יהודי שמתפלל בנוסח הנ"ל type Jew<T extends Nusach> = { name: string nusach: T } // ערך עם שדה שם ושדה נוסח const aJew = { name: 'Zundel', nusach: 'Ashkenaz' } // נסיון השמה למשתנה מסוג Jew<'Sefarad'> // TS מתריע על אי התאמה בין הטייפ לערך const test: Jew<'Sefarad'> = aJewהשורה האחרונה תפלוט שגיאה, כי טייפ מסוג
Jew<'Sefarad'>לא יכול להתפלל נוסח אשכנזמילת המפתח
extendsבדוגמה דלעיל נתקלנו לראשונה (בקורס הזה) במילת המפתח
extends, ב-TS הכוונה שלextendsהוא (לפי צורת החשיבה שהצגנו בתחילת דברינו) שהטייפ שבצד שמאלי כולו חבר בסט שמיוצג על ידי הצד הימני.
ובדוגמה הנ"ל:T extends Nusachהכוונה הוא שהפרמטרTרק מקבל טייפים שהם חברים בסטNusach
אם ננסה ליצור יהודי כזה:Jew<'foo'>נקבל שגיאה שהמחרוזתfooהוא לא חבר בקבוצתNusachנפגוש שוב את המילה
extendsבהמשךתנאים
התחביר לכתיבת תנאי ב-TS:
T extends U ? V : Wשימו לב לנקודות הבאות:
בתכנות רגיל אנחנו מורגלים לבדיקת המון דברים בתנאים, וכן לשלוט על פעולות מגוונות על ידי תנאים אלו
ב-TS לעומת זאת:- הפרט היחיד שאפשר לבדוק בתנאי הוא extends - כלומר, חברות של הצד השמאלי בצד הימני
- הדבר היחיד שאתה יכול לתלות בתנאי הזה הוא הטייפ של התוצאה של הביטוי
דוגמה לשימוש בתנאי ופונקציה ביחד:
type LabelOf<T> = T extends { label: string } ? T['label'] : 'no name'Index Signatures
אפשר לתאר את ה-shape של אובייקט בלי לפרט בדיוק את השם של השדות, במקום זה כותבים את הטייפ של המפתחות והטייפ של הערכים
לדוגמה:type X = { [key: string]: number }הכוונה בהצהרה זו הוא שמדובר באובייקט שיש בו מפתחות מסוג string וערכים מסוג number
לולאות - Mapped Types
TS לוקח את התחביר הזה שלב נוסף קדימה באמצעות mapped types
בתחביר זה אפשר לעבור בלולאה על כל הערכים האפשריים הכלולים במפתח (key) ולקבוע את הטייפ של הערך עבור אותו מפתח לפי כל לוגיקה שתבחר
דוגמה:type MyMap<T> = { [K in keyof T]: K extends `${string | undefined}foo${number}` ? string : number } type Test = MyMap<{ foo1: any, a_foo2: any, bar3: any }>keyof
כאן אנחנו נתקלים לראשונה במילת המפתח
keyof:
זה אופרטור שמחזיר union של כל שמות השדות של האופרנד שלו
למשל:keyof {foo:any, bar:any}שווה ל-'foo' | 'bar'ה"פונקציה" (יותר מקובל לקרוא לו generic type)
MyMapמקבל פרמטרT(מכיון שלא הגבלנו אותו על ידי מילת המפתחextends- הוא יכול להיות מכל סוג שהוא), ומחזיר אובייקט שיש לו אותם שדות של האובייקט המקורי, אבל אם התבנית של שם השדה מתאים לתבנית מחרוזת אופציונלית + foo + מספרי כלשהו, אז הערך של השדה חייב להיות string, אחרת הערך חייב להיות numberיותר מקובל ושימושי להשתמש ב-mapped types עם תנאי שבודק את הטייפ של ה_ערך_ של האובייקט המקורי במקום תנאי שבודק את הטייפ של ה_מפתח_ של האובייקט המקורי. עושים את זה על ידי אינדוקס ככה:
type MyMap<T> = { [K in keyof T]: T[K] extends X ? Y : Z }נראה דוגמה שימושית לזה מיד בקטע הבא
דוגמה אחרונה:
Omitבוא נבדוק את ההבנה שלך על ידי הדוגמה הבאה.
(ההגדרותExcludeו-Omitמגיעים מובנים ב-TS)// type Omit<T, K extends keyof any> = { [P in Exclude<keyof T, K>]: T[P]; } // type Exclude<T, U> = T extends U ? never : T type MyObject = { id: number foo: string bar: number } type MyObjectWithoutId = Omit<MyObject, 'id'>טוב, התעייפתי לבינתיים, אמשיך בעז"ה בהזדמנות הבאה...
-
התייעצות בתכנון מסד נתונים עבור מאגר תורניאולי נושאים אלו יעניינו אותך
https://tchumim.com/topic/1072
https://tchumim.com/topic/1047 -
התייעצות בתכנון מסד נתונים עבור מאגר תורני@pcinfogmach לא הבנתי לגמרי את דבריך.
בכל מקרה, התכוונתי רק שאת מבנה העץ תשמור כמבנה JSON. תוכן הספרים אפשר לשמור בטלאות או איך שלא תרצה -
התייעצות בתכנון מסד נתונים עבור מאגר תורני@pcinfogmach אולי תוותר על מסד טבלאי ובמקום זה תשתמש במשהו שיכול לייצג עץ נתונים בצורה יותר טבעית
אולי מבנה JSON יספק לך מענה מספיק טוב -
מישהו מכיר איזה תוסף שיכול להגביל את ההכחלה של השורה@Whenever כתב במישהו מכיר איזה תוסף שיכול להגביל את ההכחלה של השורה:
לא כ"כ מובן מה כוונתך
הכוונה ברורה לגמרי
השואל רוצה להעתיק עמודה מתוך טבלה
אני עומד מאחורי התשובה שלי שאין אפשרות כזאת כלל בדפדפן אבל אפשר להעתיק לוורד ולעשות את זה שם -
מישהו מכיר איזה תוסף שיכול להגביל את ההכחלה של השורה@THMV כתב במישהו מכיר איזה תוסף שיכול להגביל את ההכחלה של השורה:
ואני רוצה להעתיק רק את מספרי הטלפון ואני רוצה להכחיל רק את העמודה של מספרי הטלפון, ולא את כל השורה
אין אפשרות כזאת בדפדפן, אבל אפשר להעתיק את כל השורות לוורד ושם אפשר לבחור אזור בדף על ידי לחיצת alt תוך כדי גרירת העכבר
-
ניטרול לחצנים בהתקן בית חכם@ראש-פינה תעזור לנו לעזור לך
יש פה הרבה אנשים שיודעים לכתוב סקריפטים, אבל מן הסתם אין הרבה אנשים שמכירים את shelly
ככל שתמקד יותר את השאלה כך שהוא שאלה על כתיבת סקריפט ולא על ניהול shelly כך יותר סביר שתקבל תשובה
למשל אם תוכל להביא סקריפט שניסית ושגיאה שקיבלת, אולי יהיה אפשר לעזור בלי להכיר את shelly@ראש-פינה כתב בניטרול לחצנים בהתקן בית חכם:
אבל משום מה זה לא עובד לי
אחד שמשפטים המעצבנים שחוזרים על עצמם בשאלות בפורום... אתה לא זורק לנו עצם... תן קצת פירורים שיהיה עם מה לעבוד לעזור גם בלי להכיר את shelly
)