מחרוזות תבנית מתויגות כתיבה

כיצד להשתמש במחרוזות תבנית כפונקציות

היסודות: מחרוזות תבנית

לפני שדיברנו על מחרוזות תבנית מתויגות, הנקראות גם מילולי תבנית, אני רק רוצה לתת הקדמה מהירה למחרוזות תבנית באופן כללי. אל תהסס לדלג לפרק הבא אם אתה כבר יודע על מה מדובר.

מחרוזות תבנית הן סוג מיוחד של סמלי מחרוזות שיכולים להכיל ביטויים של Javascript וכן גם על פני מספר שורות. הם משתמשים בתווי ה- backtick במקום במרכאות כפולות, כפי שזה המקרה במחרוזות נפוצות.

לגבי התפשטות של תווים על פני מספר שורות, מחרוזת משותפת צריכה להכיל קו נטוי משולב עם התו "n" כדי ליצור שורה חדשה. בעזרת מחרוזות תבנית תוכלו פשוט ליצור קו חדש "מוטבע", כביכול.

// A common string as reference.
const string = "I'm just a string";

// A template string. For Typescript,
// this value is a plain 'string'-type.
const templateString = `I'm just a string as well`;

ניתן להסביר במהירות את זמינות הביטויים בתוך מחרוזת. במקום לאפשר רק סמלי מחרוזות, מחרוזות תבנית מקבלות ביטויים שרירותיים. הדוגמה הבאה מראה למה אני מתכוון בכך.

function greet(name: string) {
  // Here you see an expression
  // *embedded* inside a string.
  return `Hello, ${name}!`;
}

// "Hello, Tom!"
const greeting = greet("Tom");

// One more example, using
// Typescript's 'rest'-operator
// which allowes any number of values
// and provides them as an array,
// in our case of type 'string'.
function greetAll(...names: string[]) {
  return `Hi everybody: ${names.join(", ")}!`;
}

// "Hi everybody: Tom, Luke!"
const greetingForAll = greetAll("Tom", "Luke");

מחרוזות תבנית מתויגות

קבוצה זו של תכונות לבדה כבר תהיה נחמדה, אך מחרוזות תבנית יכולות לשמש גם כפונקציות. אתה פשוט שם מילת מפתח מול מחרוזת התבנית כדי "לתייג" אותה, ומכאן השם "מחרוזות תבניות מתויגות". הגיע הזמן לדוגמא הבאה.

// All previous examples used 'untagged'
// string literals, which means they're 
// practially just a string.
//
// But let's see how we can convert them
// to an acutal function:
function merge(template: TemplateStringsArray, ...params: string[]){
  
  // This needs some explanation:
  //
  // 'template', our first param, contains
  // all strings *inbetween the paramters*,
  // you'll see in a minute what I mean by that.
  //
  // 'params' then is an array of strings
  // that were provided as paramteres to the
  // template string.
  
  // Let's ignore the result for now.
  return "";
}

const what = "test";

// Here's the tagged template string in action.
// The tag is the function name, and like a 
// function the tagged template string can be called.
//
// Let's destruct how this will look like
// in the function defined above.
//
// 'template' = ["Just a", ""];
// 'params'   = ["test"]
const result = merge`Just a ${what}`;

// As you can see, the function splits the string
// into the string-only parts and the expressions.

כפי שאתה יכול לראות, התחביר נראה די מעניין ואולי אפילו קצת זר כאשר עובדים איתו לראשונה. כנראה שאין הרבה מאוד מקרי שימוש שיחייבו אותך ליישם מחרוזות תבנית מתויגות, אך עם זאת אנו יכולים לשחק איתו. בדוגמה הבאה והאחרונה, ריכזתי כמה מחקרי מקרה. כפי שתראה, ניתן להשתמש באופן טבעי במחרוזות תבנית מתויגות עם גנריות ולפתוח כמה אפשרויות מעניינות ליישום דרישות מסוימות.

// 
// Generic
//
// Tagged template literals can be generic, too.
function generic<T>(template: TemplateStringsArray, ...params: T[]){
    return template.join(",") + params.join(",")
}

// "A value: ,test"
console.log(generic<string>`A value: ${"test"}`);

//
// Generic (with super powers)
//
// You can specify each type and 
// also limit the number of params!
function coalesce<A, B, C>(template: TemplateStringsArray, ...params: [A, B, C]){
    return template.join(",") + params.join(",")
}

// ", - , - ,value,0,true" 
const res = coalesce<string, number, boolean>`${"value"} - ${0} - ${true}`;

//
// Different return type
//
// Also, tagged literal types don't 
// only have to return strings.
const preview = (template: TemplateStringsArray, ...params: number[]) 
  => (template2: TemplateStringsArray, ...params2: string[])
  => {
    return "what?";
}

// Note the two pairs of backticks
// after each other, we're just calling
// the returned tagged template string
// form our first one!
console.log(preview`${0}``${"a"}`);

אני מקווה שנהנית מטיול שטח מהיר למדי לאחד מהתכונות של Javascript וגם של Typescript. מחרוזות תבנית הן ככל הנראה דבר נפוץ בבסיס הקוד שלך, מחרוזות תבנית מתויגות כנראה לא, ולכן מעניין ללמוד עוד על תכונות נישה כאלה.

הצעות

קשור

נספח

שפות