Строки шаблонов с тегами в машинописном тексте

Как использовать строки шаблона как функции

Основы: строки шаблона

Прежде чем говорить о строках шаблонов с тегами, также называемых литералами шаблонов, я просто хочу дать краткое введение в строки шаблонов в целом. Не стесняйтесь переходить к следующей главе, если вы уже знаете, о чем идет речь.

Строки шаблона - это особый тип строковых символов, которые могут содержать выражения Javascript, а также занимать несколько строк. Они используют обратные апострофы вместо двойных кавычек, как в случае с обычными строками.

Что касается распределения символов по нескольким строкам, общая строка должна содержать обратную косую черту в сочетании с символом «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. Строки шаблонов, скорее всего, являются обычным явлением в вашей кодовой базе, а строки с тегами - нет, поэтому интересно узнать больше о таких нишевых функциях.

Предложения

Связанные

Приложение

Языки