Tajpita Markita Ŝablona Ŝnuro

Kiel uzi ŝablonajn ĉenojn kiel funkciojn

La bazaĵoj: Ŝablonaj Ŝnuroj

Antaŭ ol paroli pri etikeditaj ŝablonaj ĉenoj, ankaŭ nomataj ŝablonaj literaloj, mi nur volas doni rapidan enkondukon al ŝablonaj ĉenoj ĝenerale. Bonvolu salti al la sekva ĉapitro, se vi jam scias pri kio temas.

Ŝablonaj ĉenoj estas speciala speco de ĉenaj simboloj, kiuj ankaŭ povas enhavi Javaskriptajn esprimojn tra diversaj linioj. Ili uzas la malantaŭajn signojn anstataŭ duoblaj citiloj, ĉar ĝi estas la kazo por oftaj kordoj.

Koncerne la ampleksadon de signoj trans multoblaj linioj, komuna ĉeno devas enhavi malantaŭan oblikvon kombine kun la signo "n" por krei novan linion. Kun ŝablonaj ĉenoj, vi povas simple krei novan linion "enlinia", por tiel diri.

// 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`;

La havebleco de esprimoj ene de ĉeno ankaŭ povas esti rapide klarigita. Anstataŭ nur permesi ĉenajn simbolojn, ŝablonaj ĉenoj akceptas arbitrajn esprimojn. La sekva ekzemplo montras, kion mi celas per tio.

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");

Etikeditaj ŝablonaj ĉenoj

Ĉi tiu aro de funkcioj sole estus jam agrabla, sed ŝablonaj ĉenoj ankaŭ povas esti uzataj kiel funkcioj. Vi simple metu ŝlosilvorton antaŭ la ŝablonĉenon por "etikedi" ĝin, do la nomon "etikeditajn ŝablonajn ĉenojn". Tempo por la sekva ekzemplo.

// 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.

Kiel vi vidas, la sintakso aspektas sufiĉe interesa kaj eble eĉ iomete fremda kiam vi unue laboras kun ĝi. Verŝajne ne estas multaj uzokazoj, kiuj postulus vin efektivigi etikeditajn ŝablonajn ĉenojn, sed tamen ni povas ludi kun ĝi. En la sekva kaj lasta ekzemplo, mi kunmetis iujn kazajn studojn. Kiel vi vidos, etikeditaj ŝablonaj ŝnuroj nature povas esti uzataj kun generiloj kaj malfermas iujn interesajn eblojn por efektivigi iujn postulojn.

// 
// 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"}`);

Mi esperas, ke vi ĝuis ĉi tiun sufiĉe rapidan ekskurson en unu el la trajtoj de Javascript kaj ankaŭ Typescript. Ŝablonaj ĉenoj probable estas ofta afero en via kodbazo, etikeditaj ŝablonaj ĉenoj probable ne, do estas interese lerni pli pri tiaj niĉaj ecoj.