Литеральные типы в TypeScript, которые появились несколько лет назад, на самом деле произвели мини-революцию в языке, которую многие не заметили. Сегодня сложно представить себе TypeScript без этих типов и механизмов, построеных поверх них: mapped, indexer, keyof types и многие другие. В докладе я расскажу, как и почему литеральные типы появились в TypeScript и какие концепции они привнесли в язык. Поговорим также о том, почему с точки зрения разработчика анализатора TypeScript литеральные типы — это по-настоящему сложная языковая фича. Ну и конечно коснемся вопроса, как это все согласуется с реальным миром, а именно с JavaScript.
7. @JetBrains. All rights reserved
String Literal
Overloads
—
function create(p: “string"):string;
function create(p: "number"):number;
function create(p):any;
TypeScript 1.1
8. @JetBrains. All rights reserved
function create(p: true): string;
function create(p: false): number;
function create(p: boolean): string | number;
Type “true”
—
Boolean literals in overloads
17. @JetBrains. All rights reserved
class Cat { meow() }
class Dog { woof() }
function say(animal: Cat | Dog) {
if (animal instanceof Cat) {
animal.meow();
animal.woof();
}
}
Type Guard
—
18. @JetBrains. All rights reserved
class Cat { meow() }
class Dog { woof() }
function say(animal: Cat | Dog) {
if (animal instanceof Cat) {
animal.meow(); //ok, no cast
animal.woof(); //error
}
}
Type Guard
—
19. @JetBrains. All rights reserved
interface ICat { meow() }
interface IDog { woof() }
function say(animal: ICat | IDog) {
if (animal instanceof ICat) {
animal.meow();
}
}
Type Guard
—
20. @JetBrains. All rights reserved
interface ICat { meow() }
interface IDog { woof() }
function say(animal: ICat | IDog) {
if (animal instanceof ICat) {
animal.meow();
}
}
Type Guard
—
21. @JetBrains. All rights reserved
interface ICat { meow() }
interface IDog { woof() }
function say(animal: ICat | IDog) {
if (animal instanceof ICat) {
animal.meow();
}
}
//Compiled file
function say(animal) {
if (animal instanceof ICat) {
animal.meow();
}
}
Type Guard
—
28. @JetBrains. All rights reserved
type Result = {
success: boolean;
callback?() //if success=true
}
Discriminated
Union Types
—
29. @JetBrains. All rights reserved
type Result = {
success: boolean;
callback?() //if success=true
}
function process(p: Result) {
p.callback(); //ok, can throw error
}
Discriminated
Union Types
—
30. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
Discriminated
Union Types
—
31. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
Discriminated
Union Types
—
32. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
function process(p: Result) {
p.callback(); //error
}
Discriminated
Union Types
—
33. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
function process(p: Result) {
if (p.success) {
p.callback(); //ok
}
}
Discriminated
Union Types
—
34. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
function process(p: Result) {
if (p.success) {
p.callback(); //ok
}
}
Discriminated
Union Types
—
35. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
function process(p: Result) {
if (p.success) {
p.callback(); //ok
}
}
process({success : true}) //error
Discriminated
Union Types
—
36. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
function process(p: Result) {
if (p.success) {
p.callback(); //ok
}
}
process({success : true}) //error
process({success : true, callback() {}}) //ok
Discriminated
Union Types
—
37. @JetBrains. All rights reserved
type Result =
{ success: true, callback() } |
{ success: false };
function process(p: Result) {
if (p.success) {
p.callback(); //ok
}
}
process({success : true}) //error
process({success : true, callback() {}}) //ok
Discriminated
Union Types
—
46. @JetBrains. All rights reserved
Let
—
let checkValue: true = true;
let falseValue: false = checkValue; //error
let trueValue: true = checkValue; //ok
47. @JetBrains. All rights reserved
Let
—
let checkValue: true = true;
let falseValue: false = checkValue; //error
let trueValue: true = checkValue; //ok
checkValue = false; //error
49. @JetBrains. All rights reserved
Let
—
let checkValue = true;
let falseValue: false = checkValue; //error
let trueValue: true = checkValue; //ok
Type: true
50. @JetBrains. All rights reserved
Let
—
let checkValue = true;
let falseValue: false = checkValue; //error
let trueValue: true = checkValue; //ok
checkValue = false;
Type: true
51. @JetBrains. All rights reserved
Let
—
let checkValue = true;
let falseValue: false = checkValue; //error
let trueValue: true = checkValue; //ok
checkValue = false; //ok
Type: boolean
Inferred type: true
52. @JetBrains. All rights reserved
Let
—
let checkValue = true;
let falseValue: false = checkValue; //error
let trueValue: true = checkValue; //ok
checkValue = false; //ok
falseValue: false = checkValue; //ok
trueValue: true = checkValue; //error
Type: boolean
Inferred type: true
Inferred type: false
53. @JetBrains. All rights reserved
function getBoolean() {
let value: true = true;
return value;
}
Return Type
—
54. @JetBrains. All rights reserved
function getBoolean() {
let value: true = true;
return value;
} //: true
Type: true
Inferred type: true
Return Type
—
55. @JetBrains. All rights reserved
function getBoolean() {
let value = true;
return value;
}
Return Type
—
Type: boolean
Inferred type: true
56. @JetBrains. All rights reserved
function getBoolean() {
let value = true;
return value;
} //: boolean
Return Type
—
Type: boolean
Inferred type: true
57. @JetBrains. All rights reserved
function getNumber() {
let value: number | string = 1;
return value;
}
Type: number | string
Inferred type: 1
Return Type
—
58. @JetBrains. All rights reserved
function getNumber() {
let value: number | string = 1;
return value;
}
: 1
: number | string
Type: number | string
Inferred type: 1
Return Type
—
59. @JetBrains. All rights reserved
function getNumber() {
let value: number | string = 1;
return value;
}
: 1
: number
: number | string
Type: number | string
Inferred type: 1
Return Type
—
60. @JetBrains. All rights reserved
Return Type
—
function getNumber() {
let value: number | string = 1;
return value;
}
: 1
: number
: number | string
Return Type = Fixed(Inferred Type)
Type: number | string
Inferred type: 1
61. @JetBrains. All rights reserved
function getBoolean1() {
let value: true = true;
return value;
}
function getBoolean2() {
let value = true;
return value;
}
Return Type
—
62. @JetBrains. All rights reserved
function getBoolean1() {
let value: true = true;
return value; //: true
}
function getBoolean2() {
let value = true;
return value;
}
Return Type
—
63. @JetBrains. All rights reserved
function getBoolean1() {
let value: true = true;
return value; //: true
}
function getBoolean2() {
let value = true;
return value; //: true(widening)
}
Return Type
—
64. @JetBrains. All rights reserved
• Литеральные типы: расширяемый и нерасширяемый
• Литералы используемые в коде имеют расширяемый
тип
• При некоторые операциях типы расширяются до
соответствующих примитивных типов
Widening
Literal Types
—
65. @JetBrains. All rights reserved
Операции расширяющие тип:
• Вычисление возвращаемого типа функции
• Присваивание
• Вызов метода
Widening
Literal Types
—
66. @JetBrains. All rights reserved
Операции расширяющие тип*:
• Вычисление возвращаемого типа функции
• Присваивание
• Вызов метода
* Есть исключения
Widening
Literal Types
—
68. @JetBrains. All rights reserved
function getBoolean1() {
let value: true = true;
return value; //: true
}
function getBoolean2() {
let value = true;
return value; //: true(widening)
}
Literal Types
—
69. @JetBrains. All rights reserved
function getBoolean1(): boolean {
let value: true = true;
return value; //: true
}
function getBoolean2(): boolean {
let value = true;
return value; //: true(widening)
}
Literal Types
—