TypeScript实用指南-如何使用HTML,CSS和TypeScript构建Pokedex应用

本文介绍了TypeScript的基本概念、设置和配置,重点是使用TypeScript、HTML和CSS构建Pokedex应用。TypeScript提供静态类型检查,提升代码质量和可读性。通过学习,读者将了解如何利用TypeScript的类型系统,以及如何将TypeScript编译为JavaScript。
摘要由CSDN通过智能技术生成

TypeScript is a superset that needs to compile to plain JavaScript. It offers more control over your code since it uses type annotations, interfaces, classes, and static type checking to throw errors at compile-time.

TypeScript是一个超集,需要编译为纯JavaScript。 由于它使用类型注释,接口,类和静态类型检查来在编译时引发错误,因此它提供了对代码的更多控制。

TypeScript helps to enhance code quality and understandability, especially with a large codebase.

TypeScript有助于提高代码质量和易懂性,尤其是在大型代码库中。

In this guide, I will lead you through TypeScript by first learning all the basics needed to start with this great language. Then we'll finish up by building an app from scratch using HTML, CSS, and TypeScript.

在本指南中,我将通过首先学习以这种出色的语言开始所需的所有基础知识,引导您完成TypeScript。 然后,我们将使用HTML,CSS和TypeScript从头开始构建应用程序。

Let's dive in

让我们潜入

什么是TypeScript? (What is TypeScript?)

TypeScript is an object-oriented programming language developed and maintained by Microsoft. It's a superset of JavaScript, meaning that any valid JavaScript code will also run as expected in TypeScript.

TypeScript是Microsoft开发和维护的一种面向对象的编程语言。 它是JavaScript的超集,这意味着任何有效JavaScript代码也将按预期在TypeScript中运行。

TypeScript has all of the functionality of JavaScript as well as some additional features. It needs to be compiled to plain JavaScript during runtime, therefore you need a compiler to get back the JS Code.

TypeScript具有JavaScript的所有功能以及一些其他功能。 需要在运行时将其编译为纯JavaScript,因此您需要一个编译器来获取JS代码。

TypeScript uses static typing, meaning that you can give a type to a variable during declaration. And it's something that can't be done with JavaScript because it's a dynamically typed language – it does not know the data type of a variable until it assigns a value to that variable at runtime.

TypeScript使用静态类型,这意味着您可以在声明期间为变量指定类型。 这是JavaScript无法完成的,因为它是一种动态类型化的语言-它不知道变量的数据类型,直到它在运行时为该变量分配值为止。

Static type checking makes TypeScript great because it helps to throw an error at compile-time if the variable is unused or reassigned with a different type annotation. However, the error does not block the code from executing (and the JavaScript code will still be generated).

静态类型检查使TypeScript很棒,因为如果未使用变量或使用其他类型注释将其重新分配,则它有助于在编译时引发错误。 但是,该错误不会阻止代码执行(并且仍将生成JavaScript代码)。

Static typing is optional in TypeScript. If no type is defined but the variable has a value, TypeScript will infer the value as type. And if the variable has no value, the type will be set to any by default.

静态类型在TypeScript中是可选的。 如果未定义任何类型,但变量具有值,则TypeScript会将值推断为type。 而且,如果变量没有值,则默认情况下会将类型设置为任何类型。

Now, let's start using TypeScript in the next section to see it in action.

现在,让我们开始在下一部分中使用TypeScript来查看它的实际效果。

设置TypeScript (Setting up TypeScript)

As I said earlier, TypeScript needs to compile to plain JavaScript. So we need to use a tool to do the compilation. And to have access to that tool, you need to install TypeScript by running this command on the terminal.

如前所述,TypeScript需要编译为纯JavaScript。 因此,我们需要使用工具进行编译。 要访问该工具,您需要通过在终端上运行此命令来安装TypeScript。

yarn add -g typescript

Or if you are using npm:

或者,如果您使用的是npm:

npm install -g typescript

Note that here I use the -g flag to install TypeScript globally so that I can access it from anywhere.

请注意,这里我使用-g标志来全局安装TypeScript,以便可以从任何地方访问它。

By installing TypeScript, we have now access to the compiler, and we can compile our code to JavaScript.

通过安装TypeScript,我们现在可以访问编译器,并且可以将代码编译为JavaScript。

Later we will dive into it and what it does, but for now let's add a configuration file to our project. It's not mandatory to add a config file - but for many cases, it's useful to have it since it allows us to define rulesets for the compiler.

稍后我们将深入研究它及其功能,但是现在让我们向我们的项目中添加一个配置文件。 添加配置文件不是强制性的-但是在许多情况下,拥有它很有用,因为它允许我们为编译器定义规则集。

使用tsconfig配置TypeScript (Configuring TypeScript with tsconfig)

tsconfig is a JSON file that helps configure TypeScript. Having a config file is better since it helps control the behavior of the compiler.

tsconfig是一个JSON文件,可帮助配置TypeScript。 拥有配置文件会更好,因为它有助于控制编译器的行为。

To create the config file, you first need to create a new directory named Pokedex and browse into the root of the folder. Then, open it on the terminal or an IDE and run this command to generate a new TypeScript configuration file.

要创建配置文件,首先需要创建一个名为Pokedex的新目录,然后浏览到该文件夹​​的根目录。 然后,在终端或IDE上打开它,然后运行此命令以生成新的TypeScript配置文件。

tsc --init

Once the file is generated, we can now explore it on an IDE.

生成文件后,我们现在可以在IDE上对其进行浏览。

  • tsconfig.json

    tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "outDir": "public/js"
        "rootDir": "src",
        "strict": true,
        "esModuleInterop": true
        "forceConsistentCasingInFileNames": true
    },
    "include": ["src"]
}

This config file is much more verbose than what you see above – I removed the comments and unused values to make it easier to read. That said, we can now break down these values, explain each one, and see what it does.

这个配置文件比上面的内容更加冗长-我删除了注释和未使用的值,以使其更易于阅读。 就是说,我们现在可以分解这些值,解释每个值,然后看看它们的作用。

target: it specifies the ECMAScript target version when compiling the TypeScript code. Here, we target es5 to support all browsers, you can change it to ES6, ES3(it's the default if no target is specified), ES2020, etc.

target:在编译TypeScript代码时指定ECMAScript目标版本。 在这里,我们将es5为支持所有浏览器,您可以将其更改为ES6,ES3(如果未指定目标,则为默认值),ES2020等。

module: it defines the module of the compiled code. The module can be Common JS, ES2015, ES2020, etc.

模块:它定义了编译代码的模块。 该模块可以是Common JS,ES2015,ES2020等。

outDir: it specifies the output directory for the code compiled to JavaScript.

outDir:它指定编译为JavaScript的代码的输出目录。

rootDir: it defines the location where the TypeScript files that need to be compiled are located.

rootDir:它定义了需要编译的TypeScript文件所在的位置。

include: it helps define which directory needs to be compiled. If you don't have that value, the compiler will take every .ts file and compile it to JavaScript even if an output directory is defined.

包括:它有助于定义需要编译的目录。 如果没有该值,则即使定义了输出目录,编译器也会获取每个.ts文件并将其编译为JavaScript。

With that in place, we can now dive into one of the most important parts of TypeScript: the Types.

有了这个,我们现在可以深入研究TypeScript的最重要部分之一:Types。

TypeScript类型 (TypeScript Types)

Types provide a way to enhance code quality, and they also make the code easier to understand since it defines the variable types. They are optional, and help define what a given variable should have as its value. They also allow the compiler to catch errors before runtime.

类型提供了一种提高代码质量的方法,并且由于定义了变量类型,它们还使代码更易于理解。 它们是可选的,有助于定义给定变量应具有的值。 它们还允许编译器在运行时捕获错误。

TypeScript has several types such as number, string, boolean, enum, void, null, undefined, any, never, array, and tuple. We won't see all types in this guide, but keep in mind that they exist.

TypeScript具有几种类型,例如数字,字符串,布尔值,枚举,void,null,未定义,任何,从不,数组和元组。 我们不会在本指南中看到所有类型,但请记住它们存在。

Now, let's see some examples of basic Types.

现在,让我们看一些基本类型的例子。

基本TypeScript类型 (Basic TypeScript Types)

let foo: string = "test"
let bar: number = 1
let baz: string[] = ["This", "is", "a", "Test"]

As you can see here, we have three variables with different types. foo expects a string, bar, a number, and baz, an array of a string. If they receive anything else besides the type declared, an error will be thrown by TypeScript.

如您在这里看到的,我们有三个具有不同类型的变量。 foo需要一个字符串, bar ,一个数字和baz (一个字符串数组)。 如果他们收到除声明的类型以外的任何其他内容,TypeScript将引发错误。

You can also declare baz like this: let baz: Array<string> = ["This", "is", "a", "Test"].

您也可以这样声明bazlet baz: Array<string> = ["This", "is", "a", "Test"]

Now, let's try to reassign one of these variables and see how TypeScript behaves.

现在,让我们尝试重新分配这些变量之一,并查看TypeScript的行为。

let foo: string = "test"
foo = 1
Type '1' is not assignable to type 'string'

TypeScript will throw an error because we have already declared foo to expect a string as value. And this error is caught at compile-time which makes TypeScript great and useful.

TypeScript会引发错误,因为我们已经声明了foo将字符串作为值。 而且此错误是在编译时捕获的,这使TypeScript变得非常有用。

With TypeScript, types can be explicit like above, but they can be also implicit. It's better to explicitly define the type of a given value because it helps the compiler and the next developer who inherits the code. But you can also declare variables with an implicit type annotation.

使用TypeScript,类型可以像上面一样是显式的,但也可以是隐式的。 最好明确定义给定值的类型,因为它有助于编译器和继承该代码的下一个开发人员。 但是,您也可以使用隐式类型注释声明变量。

let foo = "test"
let bar = 1
let baz = ["This", "is", "a", "Test"]

TypeScript will try here to infer as much as it can to give you type safety with less code. It will take the value and define it as a type for the variable. And nothing will change regarding errors.

TypeScript将在此处尝试尽可能多地进行推断,从而以更少的代码为您提供键入安全性。 它将获取值并将其定义为变量的类型。 对于错误,什么也不会改变。

Let's try to reassign these variables to see what will happen.

让我们尝试重新分配这些变量,看看会发生什么。

foo = 7
bar = "updated"
baz = [2, true, "a", 10]

TypeScript will catch the errors like before, even if variable types are declared implicitly.

即使隐式声明了变量类型,TypeScript也会像以前一样捕获错误。

Type '7' is not assignable to type 'string'.
Type '"updated"' is not assignable to type 'number'.
Type 'true' is not assignable to type 'string'.

When dealing with an object of several properties, it can be tricky and annoying to define the types. But luckily, TypeScript has something to help you along with that use-case. So, let's dive into TypeScript Interfaces and Type aliases in the next section.

当处理具有多个属性的对象时,定义类型可能很棘手且令人讨厌。 但是幸运的是,TypeScript可以帮助您解决该用例。 因此,在下一节中,我们将深入研究TypeScript接口和Type别名。

接口和类型别名 (Interfaces and Type aliases)

Interfaces and Type aliases help us define the shape of an object-like data structures. They seem like the same thing regarding their structure, but keep in mind that they are different.

接口和类型别名可帮助我们定义类似对象的数据结构的形状。 它们在结构上似乎是一回事,但请记住它们是不同的。

However, the consensus amongst developers is to use interface whenever you can since it's in the default tslint ruleset.

但是,开发人员之间的共识是,尽可能使用interface因为它位于默认的tslint规则tslint

Now, let's create an interface and a type alias in the next section to see them in action.

现在,让我们在下一部分中创建一个接口和一个类型别名,以查看它们的实际作用。

interface ITest {
  id: number;
  name?: string;
}

type TestType = {
  id: number,
  name?: string,
}

function myTest(args: ITest): string {
  if (args.name) {
    return `Hello ${args.name}`
  }
  return "Hello Word"
}

myTest({ id: 1 })

As you can see, the structure of an interface and a type alias looks like a JavaScript object. They have to define the form of given data with TypeScript.

如您所见,接口和类型别名的结构看起来像一个JavaScript对象。 他们必须使用TypeScript定义给定数据的形式。

Notice that here, I use an optional field name by adding a question mark (?). It lets us make the property name optional. That means if no value is passed to the property name, it will return undefined as its value.

请注意,在这里,我通过添加问号( ? )使用可选的字段name 。 它使我们使属性name可选。 这意味着如果没有值传递给属性name ,它将返回undefined作为其值。

Next, we use the interface ITest as a type for the argument received by the function myTest. And as with variables, functions can also be defined to return a specific type. And here, the return value must be a string otherwise an error will be thrown by TypeScript.

接下来,我们将接口ITest用作函数myTest接收的参数的类型。 与变量一样,函数也可以定义为返回特定类型。 在这里,返回值必须是字符串,否则TypeScript将引发错误。

So far, we have covered all the basic knowledge needed to get started with TypeScript. Now, let's use it to build a Pokedex with HTML and CSS.

到目前为止,我们已经介绍了TypeScript入门所需的所有基本知识。 现在,让我们用它来构建带有HTML和CSS的Pokedex。

Let's dive in.

让我们潜入。

使用TypeScript构建Pokedex应用 (Build a Pokedex app using TypeScript)

The project we are going to build will fetch remote data from the Pokemon API and display each pokemon with TypeScript.

我们将要构建的项目将从Pokemon API中获取远程数据,并使用TypeScript显示每个Pokemon。

So, let's start by creating three new files in the root of the folder Pokedex: index.html, style.css, and src/app.ts. And for the configuration of TypeScript, we will use the same tsconfig.json file created earlier.

因此,让我们从在Pokedex文件夹的根目录中创建三个新文件开始: index.htmlstyle.csssrc/app.ts 对于TypeScript的配置,我们将使用之前创建的相同tsconfig.json文件。

Now, let's move to the markup part and add some content to the HTML file.

现在,让我们转到标记部分,然后向HTML文件中添加一些内容。

标记 (Markup)

  • index.html

    index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>TypeScript Pokedex</title>
  </head>
  <body>
    <main>
      <h1>Typed Pokedex</h1>
      <div id="app"></div>
    </main>
    <script src="public/js/app.js"></script>
  </body>
</html>

As you can see we have a relatively simple markup. There are two important things to retain though:

如您所见,我们有一个相对简单的标记。 但是,有两点要保留:

  • the id app of the div tag that will be used to append the content using TypeScript, and

    div标签的id app ,将用于使用TypeScript附加内容,以及

  • the script tag that points to the public folder and to be precise the JavaScript file that TypeScript will create for us during compile time.

    指向public文件夹的script标签,准确地说是TypeScript在编译期间为我们创建JavaScript文件。

Besides, the CSS file is a bit long, so I won't cover it – I don't want to waste your time and do want to stay focused on TypeScript. That said, we can now dive into it and start fetching data from the API.

此外,CSS文件有点长,所以我不会介绍它-我不想浪费您的时间,也不想一直专注于TypeScript。 也就是说,我们现在可以深入研究它,并开始从API中获取数据。

使用TypeScript获取和显示数据 (Fetch and display data using TypeScript)

We start the TS part by selecting the id app which is the id of the div tag.

我们通过选择id app (即div tag的id)开始TS部分。

  • src/app.ts

    src/app.ts

const container: HTMLElement | any = document.getElementById("app")
const pokemons: number = 100

interface IPokemon {
  id: number;
  name: string;
  image: string;
  type: string;
}

Here, we have a type annotation that has not to be covered yet. This is a Union Type which allows having alternative types for a given variable. That means if container is not of type HTMLElement, TypeScript will check again if the value is equal to the type after the pipe (|) symbol and so forth because you can have multiple types.

在这里,我们有一个尚未覆盖的类型注释。 这是一个联合类型,它允许给定变量具有替代类型。 这意味着如果container的类型不是HTMLElement ,TypeScript将再次检查该值是否等于竖线( | )后的类型,依此类推,因为您可以有多种类型。

Next, we have an interface IPokemon that defines the shape of a pokemon object which will be used next in the function responsible for displaying the content.

接下来,我们有一个接口IPokemon ,它定义了宠物小IPokemon对象的形状,该对象将在负责显示内容的函数中接下来使用。

  • src/app.ts

    src/app.ts

const fetchData = (): void => {
  for (let i = 1; i <= pokemons; i++) {
    getPokemon(i)
  }
}

const getPokemon = async (id: number): Promise<void> => {
  const data: Response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)
  const pokemon: any = await data.json()
  const pokemonType: string = pokemon.types
    .map((poke: any) => poke.type.name)
    .join(", ")

  const transformedPokemon = {
    id: pokemon.id,
    name: pokemon.name,
    image: `${pokemon.sprites.front_default}`,
    type: pokemonType,
  }

  showPokemon(transformedPokemon)
}

The function fetchData allows us to loop through the number of pokemon to retrieve and for each object call getPokemon with the pokemon number.

函数fetchData允许我们遍历要检索的宠物小fetchData的数量,并为每个对象调用带有宠物小getPokemon编号的getPokemon

It may take time to fetch data, so we'll use an asynchronous function that returns a Promise of type void. This last means that the function won't return a value.

提取数据可能需要一些时间,因此我们将使用异步函数,该函数返回void类型的Promise 。 这最后意味着该函数将不会返回值。

And once the data fetched, we can now create a new object transformedPokemon that mirrors the interface IPokemon, and then pass it as an argument to showPokemon().

一旦获取了数据,我们现在就可以创建一个新对象transformedPokemon ,该对象可以镜像IPokemon接口,然后将其作为参数传递给showPokemon()

  • src/app.ts

    src/app.ts

const showPokemon = (pokemon: IPokemon): void => {
  let output: string = `
        <div class="card">
            <span class="card--id">#${pokemon.id}</span>
            <img class="card--image" src=${pokemon.image} alt=${pokemon.name} />
            <h1 class="card--name">${pokemon.name}</h1>
            <span class="card--details">${pokemon.type}</span>
        </div>
    `
  container.innerHTML += output
}

fetchData()

As you can see, the function showPokemon receives as a parameter the pokemon object of type IPokemon and returns void or no value to be precise. It will just append the content to the HTML file with the help of the id container (remember, it's the div tag).

正如可以看到,功能showPokemon接收作为参数类型的小宠物对象IPokemon并返回void或无值要精确。 它将借助于id container将内容附加到HTML文件container (请记住,它是div标签)。

Great! We have now done a lot, but something is still missing because the index.html file will display nothing if you try to launch it in the browser. This is because TypeScript needs to be compiled to plain JavaScript. So, let's do that in the next section.

大! 现在,我们已经做了很多工作,但是仍然缺少一些东西,因为如果您尝试在浏览器中启动index.html文件,则该文件将不显示任何内容。 这是因为TypeScript需要编译为纯JavaScript。 因此,让我们在下一部分中进行操作。

将TypeScript编译为JavaScript (Compile TypeScript to JavaScript)

Earlier in this tutorial, we installed the TypeScript compiler which allows compiling our TS code to JavaScript. And to do so, you need to browse into the root of the project and run the following command.

在本教程的前面,我们安装了TypeScript编译器,该编译器允许将TS代码编译为JavaScript。 为此,您需要浏览到项目的根目录并运行以下命令。

tsc

This command will compile every file with a .ts extension to JavaScript. And since we have a tsconfig file, the compiler will follow the defined rules and compile only the TS files located in the src folder and put the JS code into the public directory.

该命令将编译每个扩展名为.ts JavaScript文件。 并且由于我们有一个tsconfig文件,编译器将遵循定义的规则,仅编译src文件夹中的TS文件,并将JS代码放入public目录。

The compiler also allows compiling only a single file.

编译器还只允许编译一个文件。

tsc myFile.ts

And if you do not specify a name after the TS file (myFile.ts), the compiled JS file will take the same name as the TS file.

并且,如果未在TS文件( myFile.ts )后指定名称,则编译后的JS文件将具有与TS文件相同的名称。

If you want to not execute the command on every change, just add a -w flag to let the compiler keep watching for a change and recompile the code when needed.

如果不想在每次更改时都执行命令,只需添加-w标志,以使编译器继续监视更改并在需要时重新编译代码。

tsc -w

And now if you launch the index.html file, you will see your Pokedex successfully rendered in the browser.

现在,如果您启动index.html文件,您将在浏览器中看到成功渲染的Pokedex。

Great! We have now learned the basics of TypeScript by building a Pokedex app with HTML and CSS.

大! 现在,我们已经通过使用HTML和CSS构建Pokedex应用程序来学习TypeScript的基础知识。

Preview the finished project here or find the Source Code here.

预览完成的项目在这里或找到源代码在这里

You can also find other great content like this on my blog or follow me on Twitter to get notified when I write something new.

您还可以在我的博客上找到类似的其他精彩内容,或者在Twitter上关注我以在我写新东西时得到通知。

Thanks for reading.

谢谢阅读。

资源资源 (Resources)

Here are some useful resources to dive deeper into TypeScript.

这里有一些有用的资源,可以更深入地研究TypeScript。

TypeScript Types

TypeScript类型

TypeScript Compiler Options

TypeScript编译器选项

TypeScript Handbook

打字稿手册

翻译自: https://www.freecodecamp.org/news/a-practical-guide-to-typescript-how-to-build-a-pokedex-app-using-html-css-and-typescript/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值