В этой статье мы собираемся узнать о том, как вы можете использовать машинописный текст в функциях. И как ограничить функцию, чтобы она принимала значения разных типов, чем определяемые параметры. Это будет базовое введение в функции, поскольку мы будем углубляться в эту серию, вы узнаете намного больше о функциях, таких как, как вы можете использовать псевдонимы типов или интерфейс для определения пользовательских типов для функций.

Это будет полная серия машинописных текстов, в которых вы изучите базовые темы, такие как строки, логические значения, и более сложные, такие как псевдонимы типов, перечисления, интерфейс, дженерики и т. д.

Функции

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

Параметры

Параметры функции — это имена, перечисленные в определении функции. Я возьму старый пример, который я упоминал ранее:

// This is a norma JS Function that take two number and returns the sum 
// Problem is when you call the function you can pass any value 
// It won't show error because the variable does not have any kind of type
function increaseScore(currentScore, increaseBy){
    return currentScore + increaseBy;
}

// Now we define that both parameters have `number` type and it will only take the number
// otherwise it will throw an error
function increaseScore(currentScore: number, increaseBy: number) {
  return currentScore + increaseBy;
}

Ниже приведен пример ошибки, которая будет отображаться, когда вы передаете неправильное значение функции:

function increaseScore(currentScore:number, increaseBy:number){
    console.log(currentScore + increaseBy);
}

increaseScore(10, 2) // ✅ Correct
increaseScore(10,  "2");    // ❌ Error
increaseScore(10,  [2,3,4]) // ❌ Error

Типы возврата

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

// Syntax
function funcName(para: paraType): returnType {
    //........
}


// For Example:
function greetings(name: string): string {
  return "hello" + name;
}

greetings("john");  // ✅
greetings(true);    // ❌ ERROR: Expected String

// greet is 'string' type because greetings() return stirng type
let greet = greetings("Don");
greet = 2;   // ❌ ERROR: because type is 'string'

Другие типы

пустота

void представляет возвращаемое значение функций, которые не возвращают значение. Это предполагаемый тип всякий раз, когда функция не имеет операторов return или не возвращает никакого явного значения из этих операторов return.

// This function doesn't return anything thus its return type is void
function sayHi(name: string): void {
    console.log("Hi! " + name);
}

никогда

Тип never представляет значения, которые никогда не наблюдаются. В возвращаемом типе это означает, что функция выдает исключение или завершает выполнение программы.

function handleError(errMsg: string): never {
  throw new Error(errMsg);
}

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

Дополнительные параметры

Когда вы определяете параметры, иногда вам не нужно передавать параметры. Для этого вы можете добавить ? рядом с параметром, как показано в следующем коде:

function doSomething(num?: number) {
  // ...
}
doSomething();      // ✅ OK
doSomething(10);    // ✅ OK

Примечание. Если вы используете num в качестве необязательного параметра и не передаете его в качестве аргумента, то по умолчанию будет undefined. Таким образом, вы можете обнаружить это, просто проверив (typeof num !== 'undefined').

Работа с объектом

В машинописном тексте работа с объектами может заставить вас чувствовать себя немного странно. Почему? Вы узнаете почему в конце этого раздела. Есть много случаев, когда вы можете использовать объекты. Давайте посмотрим на них один за другим -

Передача объекта в качестве параметра

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

// Destructuring an Object
function signUp({email, password}: {email: string, password: string}): void{
    console.log(email);
}

// You can also define the signUp function like the following
function signUp(user: {email:  string, password:  string}):  void{
    console.log(user.email);    
}

signUp();     // ❌ ERROR: need to pass an object
signUp({});   // ❌ ERROR: to pass an object with email & password ,
signUp({email: "[email protected]", password: "12345678"}); // ✅ Correct

Теперь, что если вы хотите передать объект с более чем двумя параметрами:

function signUp(user: { email: string; password: string }): void {
  console.log(user);
}

// Passing name in the signUp function
// ❌ ERROR: 'name' does not exist
signUp({ email: "[email protected]", password: "12345678", name: "Johnny" }); 


// Creating a separate object and then passing it with the name
// ✅ Correct and No Error, But if you use 'name' in the signUp function then you'll get an error
let newUser = { email: "[email protected]", password: "12345678", name: "Johnny" };
signUp(newUser);

Возврат объекта из функции

Вы можете вернуть объект многими способами из функции, некоторые из них показаны в следующем коде вместе с тем, правильно это или нет.

// ❌ ERROR: A function whose declared type is neither 'void' nor 'any' must return a value
// As function needs to return an object with name & age properties
function getInfo():{name:  string, age:  number}{}

// ❌ ERROR: Property 'age' is missing
// Function must have all the properties as specified (name, age)
// And It only returns the name that's why it throws an error
function getInfo():{name: string, age: number}{
  return {name: "John"};
}

// ✅ CORRECT 
// No Error Because all the things are correct
function getInfo():{name: string, age: number}{
  return {name: "John", age: 29};
}

// ❌ ERROR: 'lastName' does not exist  
// As function should return only 'name' and 'age'
// And it returns 'lastName' too
function getInfo():{name: string, age: number}{
  return {name: "John", age: 29, lastName: "Doe"};
}

// ✅ CORRECT 
// You can assign an object to some variable and then return it 
// Even if it has more properties as described
function getInfo():{name: string, age: number}{
  let user = {name: "John", age: 29, lastName: "Doe"}
  return user;
}

// ❌ ERROR: A function whose declared type is neither 'void' nor 'any' must return a value
// As you can see it has two {}
// First {} shows that it should return an object
// Second {} is function definition
// It should return an object
function getInfo():{}{}

// ✅ CORRECT 
// It returns and object that's why it works, It can have any properties because we haven't specified
function getInfo():{}{
  return {name: "John"}
}

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

Подведение итогов

В этой статье я объяснил, как можно использовать машинописный текст в функциях. И как ограничить функцию, чтобы она принимала значения разных типов, чем определяемые параметры. Это будет базовое введение в функции, поскольку мы будем углубляться в эту серию, вы узнаете намного больше о функциях, таких как, как вы можете использовать псевдонимы типов или интерфейс для определения пользовательских типов для функций.