Skip to content

Add pt-br for getting-started folder #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 29, 2022

Conversation

luk3skyw4lker
Copy link
Contributor

Opening PR for translations of files from the get-started folder. first one is already translated (TS for Functional Programmers.md)

@github-actions
Copy link
Contributor

Thanks for the PR!

This section of the codebase is owned by @khaosdoctor and @danilofuchs - if they write a comment saying "LGTM" then it will be merged.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 16, 2022

Translation of TS for the New Programmer.md

title: TypeScript for The New Programmed
short: TS for the New Programmer
layout: docs
permalink: /pt/docs/handbook/typescript-from-scratch.html

oneline: Learn TypeScript from scratch

Congratulations on choosing TypeScript as one of your first languages - you're already making good decisions!

You may have heard that TypeScript is a "flavor" or a "variant" of JavaScript. The relationship between TypeScript (TS) and JavaScript (JS) is unique among modern programming languages, so learning more about this relationship will help you understand how TypeScript adds to JavaScript.

What is JavaScript? A Brief History

JavaScript (also known as ECMAScript) began its life as a simple scriptling lingaugem for browsers. At the time it was invented, it was always expected to be used for small snippets of code embedded on a web page - writing more than a dozen lines of code would be unusual. Therefore, young browsers of the time executed such code very slowly. However, over time, JS became more and more popular and web developers began using it to create interactive experiences.

Web browser developers responded to this increased use of JS by optimizing their engines by optimizing their engines (dynamic compilation) and extending what could be done with it (adding APIs), which in turn made web developers use it even more. On modern websites, your browser is often running applications that have hundreds of thousands of lines of code. This is the long and gradual growth of the web, starting as a simple network of static pages and evolving into a platform for Applications rich of all kinds.

More than that, JS has become popular enough to be used outside the context of browsers, such as implementing JS servers using node.js. JS's "run anywhere" nature makes it an attractive choice for cross-platform development. There are many developers these days who use only JavaScript to program your entire suite of applications!

To summarize, we have a language that was developed for quick uses and then grew into a complete tool for writing applications with millions of lines. Every language has its own Individuals - uniqueness and surprises and the humble beginning of JavaScript makes it many These. Some examples:

  • The JavaScript equality operator (==) coage their arguments, leading to unexpected behavior:

    if ('' == 0) {
    	// É! mas porque??
    }
    if (1 < x < 3) {
    	// Verdadeiro para qualquer valor de x!
    }
  • JavaScript also allows you to access properties that are not present:

    const obj = { width: 10, height: 15 };
    // Porque isso é NaN? Ortografia é difícil!
    const area = obj.width * obj.heigth;

Most programming languages would throw an error when this type of situation occurred, some would do so at compile time - before any code was running. When writing small programs, such individualities are annoying but manageable; when writing applications with hundreds or thousands of lines of code, these constant surprises are a serious problem.

TypeScript: A Static Type Checker

We said before that some languages would not allow these programs to bug or run. Error detection without code execution is called static check. Determining what is an error and what is not based on the types of values being operated is called static verification of Types.

TypeScript checks a program for errors before it runs and does so based on the kinds of values, is a static type tester. For example, the last example above has an error because of the kind from obj. Here's the error that TypeScript encounters:

// @errors: 2551
const obj = { width: 10, height: 15 };
const area = obj.width * obj.heigth;

A JavaScript Typed Superset

How does TypeScript re-trigger with JavaScript then?

Syntax

TypeScript is a language that is a Superset of JavaScript: JS syntax is therefore valid in TS. Syntax refers to the way we write text to form a program. For example, this code has a syntax because there's a lack of ):

// @errors: 1005
let a = (4

TypeScript does not consider any JavaScript code to be an error because of its syntax. This means you can take any JavaScript functional code and put it into a TypeScript file without worrying about how it's written.

Types

However, TypeScript is a superset Typed, meaning that you add rules about how different types of values can be used. The previous error about obj.heigth it wasn't a mistake of syntax: is an error in the use of a value type (a kind) in an incorrect manner.

As another example, this is JavaScript code that you can run in your browser and it will display a value:

console.log(4 / []);

This syntactically cool program displays Infinity. TypeScript in turn considers splitting a number by an array a meaningless operation and will display an error:

// @errors: 2363
console.log(4 / []);

It's possible that you actually Want split a number po rum array, maybe just to see what happens, but most of the time this is a programming error. The TypeScript type checker is designed to allow correct programs while preventing as many common errors as possible. (Later, we'll learn about settings that you can use to configure how strictly TypeScript checks your code.)

If you move some code from a JavaScript file to a TypeScript file, you can see type errors depending on how the code is written. These can be legitimate problems with code or TypeScript being overconservative. Through this guide we will demonstrate how to add various TypeScript syntaxes to eliminate such errors.

Runtime Behavior

TypeScript is also a programming language that preserves the runtime behavior javascript. For example, dividing by zero in JavaScript produces Infinity rather than throwing an error at run time. As a principle, TypeScript never changes the comporance of javascript code runtime.

This means that you move JavaScript code from TypeScript, it is secure that will run the same way that TypeScript thinks the code has type errors.

Maintaining the same behavior at runtime as JavaScript is a fundamental promise of TypeScript because it means that you can easily transition between two languages without worrying about subtle differences that can cause your program to stop working.

Deleted Types

Roughly speaking, once the TypeScript compiler has finished checking your code, it Erases the types to produce the resulting "compiled" code. This means that once your code is compiled, the pure Result JS code has no type information.

This also means that TypeScript never changes the behaviour program based on the types it infers. The end of this is that while you see type errors during compilation, the type system itself has no influence on how your program works when it runs.

Finally, TypeScript does not provide any additional runtime library. Your programs will use the same standard (or external) libraries as JavaScript programs, so there are no additional TypeScript-specific tools to learn.

Learning JavaScript and TypeScript

We often see the question "Should I learn JavaScript or TypeScript?".

The answer is that you can't learn TypeScript without learning JavaScript! TypeScript shares syntax and runtime behavior with JavaScript, so anything you want to learn about JavaScript will be helping you learn TypeScript at the same time.

There are many, many resources available for programmers to learn JavaScript; you No you should ignore these features if you are writing TypeScript. For example, there are about 20 times as many questions in StackOverflow that are marked with javascript than with typescriptbut All the issues javascript also apply to TypeScript.

If you find yourself looking for something like "how to organize a list in TypeScript," remember: TypeSript is the JavaScript execution environment with build-time type checker. The way you organize a list in TypeScript is the same in JavaScript. If you find a feature that uses TypeScript directly this is great too, but don't just think that you need specific TypeScript answers to day-to-day questions about how to achieve execution environment tasks.

Next Steps

This was a short summary of the syntax and tools used in TypeScript in day-to-day life. From here, you can:

Translation of TS for OOPers.md

title: TypeScript for Java/C# programmers
short: TS for Java/C# programmers
layout: docs
permalink: /pt/docs/handbook/typescript-in-5-minutes-oop.html

oneline: Learn TypeScript if you have a background with object-oriented languages

TypeScript is a popular choice for programmers accustomed to other static-typing languages such as C# and Java.

The TypeScript type system offers many of the same benefits, such as better code completion, premature error detection, and clearer commotion between parts of your program. While TypeScript provides many familiar features for these developers, it is worth taking a step back to see how much JavaScript (as a consequence TypeScript) differs from object-oriented languages. Understanding these differences will help you write javascript code better and avoid common pitfalls that programmers who go directly from C#/Java to TypeScript fall.

Co-learning JavaScript

If you're already familiar with JavaScript but are primarily a Java or C# programmer, this introductory page can help explain some of the common misconceptions and pitfalls you might be susceptible to. Some of the forms of TypeScript type templates are quite different from Java or C# and it's important to keep those in mind when learning TypeScript.

If you are a Java or C# developer who is new to JavaScript in general, we recommend learning a bit of JavaScript without types first to understand the behavior of JavaScript at runtime. Because TypeScript doesn't change the way your code is Run, you'll still have to learn how JavaScript works to write code that actually does something!

It is important to remember that TypeScript uses the same execution environment that JavaScript, then any resources on how to perform certain behavior at runtime (convert a string to a number, display an alert, write a file to disk, etc.) will always apply equally to TypeScript programs. Don't limit yourself to specific TypeScript features!

Rethinking the Class

C# and Java are what we can call languages compulsorily object-oriented. In these languages, the class is the basic unit of code organization and also the basic container of all data and behavior at run time. Forcing all functionality and data to be contained in classes can be a good domain model for some problems, but not every domain Need be represented in this way.

Free functions and Data

In JavaScript, functions can exist anywhere and data can be sent freely without being within a class or struct pre-defined. This flexiblity is extremely powerful. "Free" functions (those that are not associated with a class) working on the data without a subject orientation hierarchy involved tend to be the preferred model for writing javascript programs.

Static Classes

Additionally, certain C# and Java constructs such as singletons and static classes are unnecessary in TypeScript.

POO in TypeScript

With that said, you can still use classes if you want! Some issues are suitable to be resolved by traditional POO hierarchy, and TypeScript support for JavaScript classes will make these templates even more powerful. TypeScript supports many common patterns such as implementing interfaces, inheritance, and static methods.

We will cover classes later in this guide.

Rethinking Types

The TypeScript understanding of a kind is currently quite different from c# or java. Let's explore some differences.

Rated Type System Reified

In C# or Java, any given value or object has an exact type - be it null, a primitive, or a known class. We can call methods like value.GetType() or value.getClass() to fetch the exact type at run time. The definition of this type will reside in a class somewhere with some name, and we cannot use two classes with similar formats in place of each other unless there is an explicit inheritance relationship or a common interface implemented.

These aspects describe a system of type nominal, reified. The types we write in code are present at runtimes, and these types are related by their statements, not their structures.

Types as Sets

In C# or Java, it is significant to think of a one-to-one match between the runtime types and their build-time declarations.

In TypeScript, it is better to think of a type as a set of values who share something in common. Because types are only sets, a particular value can belong to the many sets at the same time.

Once you start thinking about types like sets, certain operations become quite natural. For example, in C#, it's quite strange to send a value that can be one string or a int, because there is no single type that represents this value.

In TypeScript, this becomes quite natural once you realize that every type is just a set. How do you describe a value that can belong to the set string or the whole number? It simply belongs to the union of these sets: string | number.

TypeScript provides a number of mechanisms for working with types in the form of sets and you will find that they are more intuitive if you think of types as sets.

Structural Types Erased

In TypeScript, objects No are of an exact type. For example, if we build an object that satisfies an interface, we can use this object where that interface is expected even if there is no delcartive relationship between the two.

interface Ponto {
	x: number;
	y: number;
}
interface Nomeada {
	nome: string;
}

function exibirPonto(point: Ponto) {
	console.log('x = ' + point.x + ', y = ' + point.y);
}

function exibirNome(x: Nomeada) {
	console.log('Olá, ' + x.nome);
}

const obj = {
	x: 0,
	y: 0,
	nome: 'Origem'
};

exibirPonto(obj);
exibirNome(obj);

The TypeScript type system is structural, not nominal: We can use obj as a Ponto because the properties x and y are both numbers. The relationship between the types is determined by the properties they contain, if they have been declared with a certain relationship.

The TypeScript type system is also not reified: There is nothing at run time that we will say if that obj is a Ponto. In fact, the type Ponto is not present in no way at runtime.

Going back to the idea of tipos como conjuntos, we may think that obj is a member of both the value set Ponto how much of the set of values Nomeada.

Consequences of Structural Typing

POO programmers are often surprised by the particular aspects of structural typing.

Empty Types

The first is that the empty type seems to defy expectations:

class Vazio {}

function fn(arg: Vazio) {
	// fazer algo?
}

// Sem erro, mas isso não é um 'Vazio' ?
fn({ k: 10 });

TypeScript determines whether the call to fn is valid for checking whether the argument provided is a Vazio valid. He does this by examining the estrutura from { k: 10 } and class Vazio { }. We can see that { k: 10 } has all the properties that Vazio has because Vazio has no properties. So it's a valid call.

This may seem very surprising, but ultimately it is a very similar relationship to one applied in nominal POO languages. A subclass cannot remove a property of its base class, because doing so would destroy the natural subtype relationship between the derived class and its base. Structural typing systems simply identify this relationship implicitly by describing subtypes in terms of having properties of compatible types.

Identical Types

Another frequent source of surprise comes with identical types:

class Carro {
	dirigir() {
		// pressionar o acelerador
	}
}
class Golfer {
	dirigir() {
		// jogar a bola para longe
	}
}

// Sem erro?
let w: Carro = new Golfer();

Again, this is not a mistake because the Structures of these classes are the same. While this may seem like a potential source of confusion, in practice, identical classes that should not be related are not common.

We learn more about how classes relate to each other in the Classes chapter.

Reflection

POO programmers are accustomed to being able to pick up the kind of any value, even a generic:

// C#
static void TipoDoLog<T>() {
    Console.WriteLine(typeof(T).Name);
}

Because the TypeScript type system is completely erased, information about e.g. the instantiation of a generic type parameter is not available at run time.

JavaScript has some limited primitives like typeof and instanceof, but remember that these operators will still work on the values because they exist in the output code with type deleted. For instance typeof (new Carro()) Is objectNo Carro or "Carro"

Next Steps

This documentation is a high-level summary of syntax and types you would use in code on a day-to-day business. Hence you should:

Translation of TS for JS Programmers.md

title: TypeScript for JavaScript programmers
short: TypeScript for JavaScript programmers
layout: docs
permalink: /pt/docs/handbook/typescript-in-5-minutes.html

oneline: Learn how TypeScript extends JavaScript

TypeScript has an unusual relationship with JavaScript. TypeScript offers all javascript features, and an additional layer at the top of this: the TypeScript type system.

For example, JavaScript offers language primitives such as string and number, but does not consistently check that you have assigned these. TypeScript checks.

This means that your existing JavaScript code is also TypeScript code. The main benefit of TypeScript is that it can highlight unexpected behavior in your code, reducing the chance of bugs.

This tutorial provides a summary of TypeScript, focusing on your type system.

Types by Inference

TypeScript knows the JavaScript language and will generate types for you in many cases. For example when creating a variable and assigning it to a certain value, TypeScript uses the value as its type.

let olaMundo = 'Olá Mundo';
//  ^?

Understanding how JavaScript works, TypeScript can build a system of types that accepts JavaScript code but has types. This provides a system of types without the need to add extra characters to make the types explicit in your code. This is how TypeScript knows that olaMundo is a string in the example above.

You may have already written JavaScript code in Visual Studio Code, and had auto-complete from the editor. Visual Studio Code uses TypeScript under the cloths to make it easier to work with JavaScript.

Defining Types

You can use a wide variety of project patterns types in JavaScript. However, some design patterns make automatic type inference difficult (for example, patterns that use dynamic programming). To cover these cases, TypeScript supports a JavaScript extension, which provides places for you to tell TypeScript what the types should be.

For example, to create an objteo with an inferred type that includes name: string and id: number, you can write:

const usuario = {
	nome: 'Hayes',
	id: 0
};

You can explicitly describe the shape of this object using a declaration of interface:

interface Usuario {
	nome: string;
	id: number;
}

You can then declare a JavaScript object according to the format of your new interface using syntax : TypeName after the declaration of a variable:

interface Usuario {
	nome: string;
	id: number;
}
// ---cut---
const usuario: Usuario = {
	nome: 'Hayes',
	id: 0
};

If you provide an object that does not match the interface you provided, TypeScript will alert you:

// @errors: 2322
interface Usuario {
	nome: string;
	id: number;
}

const usuario: Usuario = {
	nomeDeUsuario: 'Hayes',
	id: 0
};

Since JavaScript supports classes and object-oriented programming, So does TypeScript. You can use the interface declaration with classes:

interface Usuario {
	nome: string;
	id: number;
}

class UsuarioConta {
	nome: string;
	id: number;

	constructor(nome: string, id: number) {
		this.nome = nome;
		this.id = id;
	}
}

const usuario: Usuario = new UsuarioConta('Murphy', 1);

You can use interfaces to tipar parameters and return values in functions:

// @noErrors
interface Usuario {
	nome: string;
	id: number;
}
// ---cut---
function buscarUsuarioAdmin(): Usuario {
	//...
}

function deletarUsuario(usuario: Usuario) {
	// ...
}

There is already a small set of primitive types available in JavaScript: boolean, bigint, null, number, string, symboland undefined, which you can use in an interface. TypeScript extends this list with a few more like any (allow anything), unknown (ensure that someone using this type declares what type it is), never (it is not possible for this type to happen), and void (a function that returns undefined or that has no return value).

You will see that there are two syntaxes for constructing types: Interfaces and Types. You should prefer interface. Use type when you need specific features.

Composing Types

With TypeScript, you can create complex types by combining simple ones. There are two popular ways to do this: with unions, and with generics.

Unions

With a union, you can declare that a type can be one of many. For example, you can describe a type boolean as being true or false:

type MeuBooleano = true | false;

Note: if you hover over the MeuBoleano above, you will see that it is classified as boolean. This is a property of the Structural Type System. More on that below.

A popular use case of union types is to describe the value that a set of Literals from string or number may have:

type EstadoDaJanela = 'aberto' | 'fechado' | 'minimizado';
type EstadosDeBloqueio = 'trancado' | 'destrancado';
type NumerosImparesMenoresQue10 = 1 | 3 | 5 | 7 | 9;

Unions provide a way to manage different types as well. For example, you might have a function that receives as an argument a array or a string:

function buscarComprimento(obj: string | string[]) {
	return obj.length;
}

To know the type of a variable, use typeof:

Kind Predicate
string typeof s === "string"
Number typeof n === "number"
Boolean typeof b === "boolean"
Undefined typeof undefined === "undefined"
function typeof f === "function"
array Array.isArray(a)

For example, you can make a function return different types depending on whether a string or array is passed:

function envolverEmArray(obj: string | string[]) {
  if (typeof obj === "string") {
    return [obj];
//          ^?
  }
  return obj;
}

Generic

Generics provide variables for types. A common example is an array. An array without generics can contain anything. An array with generics can describe the values that that array contains.

type ArrayDeStrings = Array<string>;
type ArrayDeNumeros = Array<number>;
type ObjetoComNomeArray = Array<{ nome: string }>;

You can declare your own types using generics:

// @errors: 2345
interface Mochila<Tipo> {
	adicionar: (obj: Tipo) => void;
	buscar: () => Tipo;
}

// Esse é um atalho para dizer ao Typescript que há uma
// constante chamada mochila, e não se preocupar de onde ela veio.
declare const mochila: Mochila<string>;

// objeto é uma string, porque nós o declaramos acima como a parte variável de Mochila.
const objeto = mochila.buscar();

// Já que a variável mochila é uma string, você não pode passar um número para a função adicionar.
mochila.adicionar(23);

Structural Types System

One of the central principles of TypeScript is that type checking is focused on format that the values have. This is sometimes called "duck typing" or "structural typing".

In a structured typing system, if two objects have the same format, they are considered of the same type.

interface Ponto {
	x: number;
	y: number;
}

function exibirPonto(p: Ponto) {
	console.log(`${p.x}, ${p.y}`);
}

// exibe "12, 26"
const ponto = { x: 12, y: 26 };
exibirPonto(ponto);

The variable ponto is never declared to be of the kind Ponto. However, TypeScript comms the ponto to the format of Ponto in the type check. They have the same format, so the code passes.

Type matching only requires that a subset of object fields match:

// @errors: 2345
interface Ponto {
	x: number;
	y: number;
}

function exibirPonto(p: Ponto) {
	console.log(`${p.x}, ${p.y}`);
}
// ---cut---
const ponto3 = { x: 12, y: 26, z: 89 };
exibirPonto(ponto3); // logs "12, 26"

const rect = { x: 33, y: 3, largura: 30, altura: 80 };
exibirPonto(rect); // logs "33, 3"

const color = { hex: '#187ABF' };
exibirPonto(color);

There is no difference between how classes and objects conform to formats:

// @errors: 2345
interface Ponto {
	x: number;
	y: number;
}

function exibirPonto(p: Ponto) {
	console.log(`${p.x}, ${p.y}`);
}
// ---cut---
class PontoVirtual {
	x: number;
	y: number;

	constructor(x: number, y: number) {
		this.x = x;
		this.y = y;
	}
}

const novoPontoV = new PontoVirtual(13, 56);
exibirPonto(novoPontoV); // logs "13, 56"

If the object or class has all the required properties, TypeScript will say that they match, regardless of the implementation details.

Next Steps

This documentation is a high-level summary of syntax and types you would use in code on a day-to-day business. Hence you should:

Translation of TS for Functional Programmers.md

title: TypeScript for Functional Programmers
short: TS for Functional Programmers
layout: docs
permalink: /pt/docs/handbook/typescript-in-5-minutes-func.html

oneline: Learn Typescript if you have a history with functional programming

Typescript began its life in an attempt to bring traditionally object-oriented types to JavaScript so that programmers at Microsoft could bring traditionally object-oriented programs to the web. As it developed, the Typescript type system evolved into template code written by native JavaScripters. The resulting system is powerful, interesting and confusing.

This introduction is designed to help Haskell or ML programmers who want to learn Typescript. It describes how the Typescript type system differs from the Haskell type system. It also describes the unique functionality of the Typescript typesystem that has ancestry in JavaScript code modeling.

This introduction does not cover object-oriented programming. In practice, object-oriented programming in Typescript is similar to other popular languages with OO functionality.

Prerequisites

In this introduction, I take it that you have the following knowledge:

  • How to program in JavaScript, the good parts.
  • Type syntax of a c-descending language.

If you need to learn the good parts of Javascript, read JavaScript: The Good Parts. You may be able to skip the book if you know how to write programs in a call-by-value lexical scope dread language with too much mutability and not much else. R4RS Scheme is a good example.

The C++ Programming Language is a good place to learn about c-style syntax. x: string rather than string x.

Concepts that are not in Haskell

Native Types

JavaScript defines 8 native types:

Type Explanation
Number a dual-precision floating point IEEE 754.
String an immutable String UTF-16.
BigInt integers in arbitrary precision format.
Boolean true and false.
Symbol a single value used as a key.
Null equivalent to the unit type.
Undefined also equivalent to the unit type.
Object similar to records.

See MDN for more details.

Typescript has the corresponding primitive types for the native types:

  • number
  • string
  • bigint
  • boolean
  • symbol
  • null
  • undefined
  • object

Other important typescript types

Type Explanation
unknown the guy at the top.
never the guy at the end.
literal object Eg { property: Type }
void a subtype of undefined to be used as a return type.
T[] mutable arrays, also written as Array<T>
[T, T] tuples, which have fixed size but are changeable
(t: T) => U Functions

Notes:

  1. Syntax of functions include the names of parameters. It's pretty hard to get used to it!

    let fst: (a: any, b: any) => any = (a, b) => a;
    
    // ou mais precisamente:
    
    let fst: <T, U>(a: T, b: U) => T = (a, b) => a;
  2. Object literal type syntax precisely mirrors the literal object value syntax:

    let o: { n: number; xs: object[] } = { n: 1, xs: [] };
  3. [T, T] is a subtype of T[]. This is different in Haskell, where tuples are not list-related.

Types in boxes

Javascript has types in boxes equivalent to primitive types that contain methods that programmers associate with these types. Typescript reflects this with, for example, the difference between the primitive type number and the boxed type Number. Boxed types are rarely required, since their methods return primitives.

(1).toExponential();
// é equivalente a
Number.prototype.toExponential.call(1);

Note that to call a method on a literal numeric it has to be in parentheses to assist the translator.

Gradual typing

Typescript uses type any whenever you can't tell what kind of expression should be. Compared to the Dynamic, call the any of a kind is an exaggeration. It just disables the type checker wherever it appears. For example, you can enter any value in a any[] without marking the value in any way:

// com "noImplicitAny": false no tsconfig.json, anys: any[]
const anys = [];
anys.push(1);
anys.push('oh não');
anys.push({ qualquer: 'coisa' });

And you can use expressions of the type any anywhere:

anys.map(anys[1]); // oh não, "oh não" não é uma função

any is contagious, too — if you initialize a variable with an expression of the type any, the variable has the type any also.

let sepsis = anys[0] + anys[1]; // isso poderia significar qualquer coisa

To have an error when Typescript produces a anyUse "noImplicitAny": trueor "strict": true in tsconfig.json.

Structural typing

Structural typing is a familiar concept for most functional programmers, even though Haskell and most MLs are not stylistually typed. Its basic form is quite simple:

// @strict: false
let o = { x: 'olá', extra: 1 }; // ok
let o2: { x: string } = o; // ok

Here, the literal object { x: "hi", extra: 1 } has a corresponding literal type { x: string, extra: number }. This type is attributable to { x: string } since it has all the required properties and these properties have atribible types. The extra property has no previous assignment, it only forms a subtype of { x: string }.

Named types only give a name to a type; for assignment purposes there is no difference between the type name Um and the type interface Dois down. They both have a property p: string. (Type names behave differently than interfaces with respect to recursive definitions and type parameters however.)

// @errors: 2322
type Um = { p: string };
interface Dois {
	p: string;
}
class Tres {
	p = 'Olá';
}

let x: Um = { p: 'oi' };
let dois: Dois = x;
dois = new Tres();

Unions

In Typescript, the union types are marked. In other words, they are not discriminated unions as data in Haskell. However, you can often discriminate types in a union using native tags or other properties.

function começar(
	arg: string | string[] | (() => string) | { s: string }
): string {
	// isso é super comum em Javascript
	if (typeof arg === 'string') {
		return casoComum(arg);
	} else if (Array.isArray(arg)) {
		return arg.map(casoComum).join(',');
	} else if (typeof arg === 'function') {
		return casoComum(arg());
	} else {
		return casoComum(arg.s);
	}

	function casoComum(s: string): string {
		// finalmente, apenas converta uma string para outra string
		return s;
	}
}

string, Array and Function have predicates of native types, conveniently bringing the object type to branch else. It is possible, however, to generate unions that are difficult to differentiate at runtime, for new code, it is better to build only broken unions.

The following types have native predicates:

Kind Predicate
string typeof s === "string"
Number typeof n === "number"
Bigint typeof m === "bigint"
Boolean typeof b === "boolean"
Symbol typeof g === "symbol"
Undefined typeof undefined === "undefined"
function typeof f === "function"
array Array.isArray(a)
object typeof o === "object"

Note that functions and arrays are run-time objects, but have their own predicates.

Intersections

In addition to unions, Typescript also has intersections:

type Combinada = { a: number } & { b: string };
type Conflitante = { a: number } & { a: string };

Combinada has two properties, a and b, as if they were written as a single type of literal object. Intersections and unions are recursive in cases of conflict, so Conflitante.a: number & string.

Unit types

Unit types are subtypes of primitive types that contain exactly one primitive value. For example, the string foo has the same kind of "foo". Since JavaScript has no native enums, it is common to use a set of known strings. Unions of literal string types allow TypeScript to have this pattern:

declare function encher(
	s: string,
	n: number,
	direction: 'esquerda' | 'direita'
): string;

encher('hi', 10, 'esquerda');

When necessary, the compiler Extends — converts to a super type — the unit type for a primitive type, such as "foo"
towards string. This happens when mutability is used, which can hinder the use of mutable variables:

// @errors: 2345
declare function encher(
	s: string,
	n: number,
	direction: 'esquerda' | 'direita'
): string;
// ---cut---
let s = 'direita';
encher('hi', 10, s); // error: 'string' is not assignable to '"esquerda" | "direita"'

How the error happens:

  • "direita": "direita"
  • s: string because "direita" expands to string when assigned to a mutable variable.
  • string is not attributable to "esquerda" | "direita"

You can resolve this with a type notation for s, but this prevents attributions to s of variables that are not of the type "esquerda" | "direita".

declare function encher(
	s: string,
	n: number,
	direction: 'esquerda' | 'direita'
): string;
// ---cut---
let s: 'esquerda' | 'direita' = 'direita';
encher('hi', 10, s);

Concepts similar to Haskell

Contextual typing

TypeScript has some obvious places where it can infer types, such as variable declarations:

let s = 'Eu sou uma string!';

But it also infers types in some other places that you might not expect if you've worked with other languages with C-based syntaxes:

declare function map<T, U>(f: (t: T) => U, ts: T[]): U[];
let sns = map(n => n.toString(), [1, 2, 3]);

Here n: number in this example as well, despite the fact that T and U were not inferred before the call. In fact, before [1,2,3] have been used to infer T=number, the type of return of n => n.toString() is used to infer U=stringCausing sns have the type string[].

Note that inference will work in any order, but intellisense will only work from right to left, so TypeScript prefers to declare map with the first array:

declare function map<T, U>(ts: T[], f: (t: T) => U): U[];

Contextual typing also works recursively between literal objects, and on unit types that would be inferred as string or number. And it can infer context return types:

declare function rodar<T>(thunk: (t: T) => void): T;
let i: { inferencia: string } = rodar(o => {
	o.inferencia = 'INSIRA O ESTADO AQUI';
});

The type of o is determined to be { inferencia: string } because

  1. Declaration initiators are contextually typed by the delcaração of the
    kind: { inference: string }.
  2. The return type of a call uses the contextual type for inferences,
    then the compiler infers that T={ inferencia: string }.
  3. Arrow functions use contextual typing to tipar their parameters,
    then the compiler delivers o: { inferencia: string }.

And it does this while you're typing, so that before you type o., you have suggestions for the property inferencia, along with any other properties you would have in a real program.
All in all, this feature can make the TypeScript inference look a bit like a type inference unification engine, but it's not.

Type nicknames

Type nicknames are mere nicknames, as well as type in Haskell. The compiler will try to use the nickname name wherever it has been used in the source code, but it will not always succeed.

type Tamanho = [number, number];
let x: Tamanho = [101.1, 999.9];

The closest equivalent to newtype is a marked intersection:

type FString = string & { __compileTimeOnly: any };

One FString it's like a normal string, except that the compiler thinks it has a property called __compileTimeOnly that doesn't really exist. This means that FString can still be assigned to string, but not the other way around.

Discriminated Unions

The closest equivalent to the data is a union of types with discriminating properties, typically called discriminated unions in TypeScript:

type Forma =
	| { tipo: 'circulo'; raio: number }
	| { tipo: 'quadrado'; x: number }
	| { tipo: 'triangulo'; x: number; y: number };

Unlike Haskell, tagging, or discriminating, is just a property in each type object. Each variant has an identical property with a different unit type. This is still a normal type union; or | in front is an optional part of the type join syntax. You can discriminate the members of a union using normal JavaScript code:

type Forma =
	| { tipo: 'circulo'; raio: number }
	| { tipo: 'quadrado'; x: number }
	| { tipo: 'triangulo'; x: number; y: number };

function area(s: Forma) {
	if (s.tipo === 'circulo') {
		return Math.PI * s.raio * s.raio;
	} else if (s.tipo === 'quadrado') {
		return s.x * s.x;
	} else {
		return (s.x * s.y) / 2;
	}
}

Note that the return type of area is inferred as number because TypeScript knows that the function is total. If any variant is not covered, the return type will be number | undefined.

Also, unlike Haskell, common properties appear in any union, so you can usually discriminate against multiple union members:

type Forma =
	| { tipo: 'circulo'; raio: number }
	| { tipo: 'quadrado'; x: number }
	| { tipo: 'triangulo'; x: number; y: number };
// ---cut---
function altura(s: Forma) {
	if (s.tipo === 'circulo') {
		return 2 * s.raio;
	} else {
		// s.tipo: "quadrado" | "triangulo"
		return s.x;
	}
}

Type Parameters

Like most languages descending from C, TypeScript requests the declaration of type parameters:

function levantarArray<T>(t: T): Array<T> {
	return [t];
}

There is no case requirement, but type parameters are conventionally single capital letters. Type parameters can also be restricted to a type, which behaves somewhat like class constraints:

function primeiro<T extends { length: number }>(t1: T, t2: T): T {
	return t1.length > t2.length ? t1 : t2;
}

TypeScript can usually infer type arguments from a call based on the type of arguments, so type arguments are not usually required.

Because TypeScript is structural, it does not need any type parameters as many nominal systems. Specifically, they are not required to make a polymorphic function. Type parameters should be used only for propagate type information, such as restricting parameters to be of the same type:

function comprimento<T extends ArrayLike<unknown>>(t: T): number {}

function comprimento(t: ArrayLike<unknown>): number {}

In the first comprimento, T is not necessary; note that it is only referenced once, so it is not being used to restrict the type of the return value or other parameters.

Top types

TypeScript has no higher types, so the following is not allowed:

function comprimento<T extends ArrayLike<unknown>, U>(m: T<U>) {}

Point-free programming

Point-free programming — Heavy use of currying and composition functions — is possible in JavaScript, but can be verbose. In TypeScript, type inference often fails for point-free programs, so you'll end up specifying type parameters rather than value parameters. The result is so verbose that it is usually best to avoid point-free progamation.

Module system

The modern syntax of JavaScript modules is similar to Haskell's, except that any file with import or export is implicitly a module:

import { value, Type } from 'npm-package';
import { other, Types } from './local-package';
import * as prefix from '../lib/third-package';

You can also import commonjs modules — modules written using the node mobile system.js:

import f = require('single-function-package');

You can export with an export list:

export { f };

function f() {
	return g();
}
function g() {} // g is not exported

Or by marking each export individually:

export function f { return g() }
function g() { }

The latter is more common but both are allowed, even when in the same file.

readonly and const

In JavaScript, mutability is the default, although it allows declarations of variables with const to declare that reference is changeable. The referto is still mutable:

const a = [1, 2, 3];
a.push(102); // ):
a[0] = 101; // D:

TypeScript has additional modifier readonly for properties.

interface Rx {
	readonly x: number;
}
let rx: Rx = { x: 1 };
rx.x = 12; // erro

It also has a mapped type Readonly<T> that makes all properties be readonly:

interface X {
	x: number;
}
let rx: Readonly<X> = { x: 1 };
rx.x = 12; // erro

And there's a specific type ReadonlyArray<T> that removes methods of side effects and prevents writing to array indexes, as well as special syntax for this type:

let a: ReadonlyArray<number> = [1, 2, 3];
let b: readonly number[] = [1, 2, 3];
a.push(102); // erro
b[0] = 101; // erro

You can also use constant assertiveness, which operates on literal objects and arrays:

let a = [1, 2, 3] as const;
a.push(102); // erro
a[0] = 101; // erro

However, none of these options are the default, so they are not consistently used in TypeScript code

Next Steps

This documentation is a high-level summary of syntax and types you would use in code on a day-to-day business. Hence you should:

Generated by 🚫 dangerJS against 362b449

@luk3skyw4lker luk3skyw4lker marked this pull request as draft January 16, 2022 21:48
@luk3skyw4lker luk3skyw4lker marked this pull request as ready for review January 21, 2022 12:55
@luk3skyw4lker luk3skyw4lker changed the title [WIP]: Add pt-br TS for Functional Programmers.md Add pt-br for getting-started folder Jan 21, 2022
@khaosdoctor
Copy link
Contributor

LGTM

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2022

There was an issue merging, maybe try again khaosdoctor. Details

@khaosdoctor
Copy link
Contributor

LGTM

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2022

There was an issue merging, maybe try again khaosdoctor. Details

@khaosdoctor
Copy link
Contributor

So I guess we have a problem, and I can't see the results, @orta can you save us?

@khaosdoctor
Copy link
Contributor

LGTM

@github-actions
Copy link
Contributor

There was an issue merging, maybe try again khaosdoctor. Details

Copy link
Contributor

@danilofuchs danilofuchs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great Job! Let me try merging
LGTM

@luk3skyw4lker
Copy link
Contributor Author

@danilofuchs @orta @khaosdoctor

Is this PR gonna be merged?

@khaosdoctor
Copy link
Contributor

We're trying but we can't merge it. Apparently it's not working anymore

@khaosdoctor
Copy link
Contributor

LGTM

@github-actions github-actions bot merged commit 1782405 into microsoft:main Aug 29, 2022
@github-actions
Copy link
Contributor

Merging because @khaosdoctor is a code-owner of all the changes - thanks!

@khaosdoctor
Copy link
Contributor

YAY IT WORKED

@luk3skyw4lker luk3skyw4lker deleted the pt-br-get-started branch August 29, 2022 18:01
@luk3skyw4lker
Copy link
Contributor Author

YEAHHHHHHHH

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants