Tải bản đầy đủ (.pdf) (82 trang)

Type Script succinctly by Steve Fenton

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.11 MB, 82 trang )



1




2


By
Steve Fenton
Foreword by Daniel Jebaraj












3
Copyright © 2013 by Syncfusion Inc.
2501 Aerial Center Parkway
Suite 200
Morrisville, NC 27560
USA


All rights reserved.

mportant licensing information. Please read.
This book is available for free download from www.syncfusion.com on completion of a
registration form.
If you obtained this book from any other source, please register and download a free copy from
www.syncfusion.com.
This book is licensed for reading only if obtained from www.syncfusion.com.
This book is licensed strictly for personal, educational use.
Redistribution in any form is prohibited.
The authors and copyright holders provide absolutely no warranty for any information provided.
The authors and copyright holders shall not be liable for any claim, damages, or any other
liability arising from, out of, or in connection with the information in this book.
Please do not use this book if the listed terms are unacceptable.
Use shall constitute acceptance of the terms listed.
SYNCFUSION, SUCCINCTLY, DELIVER INNOVATION WITH EASE, ESSENTIAL, and .NET
ESSENTIALS are the registered trademarks of Syncfusion, Inc.

dited by
This publication was edited by Praveen Ramesh, director of development, Syncfusion, Inc.

I
E



4
Table of Contents
The Story behind the Succinctly Series of Books 8
About the Author 10

Introduction 11
Is TypeScript the Answer? 11
Who is This Book For? 11
What is Missing? 12
Code Samples 12
Notes 12
Chapter 1 Concepts in TypeScript 13
Code organization 13
TypeScript Glossary 14
Program 14
Module 14
Interface 14
Class 14
Function 14
Variable 15
Enumeration 15
Scope 15
Compilation 15
ECMAScript 3 15
ECMAScript 5 16
ECMAScript 6 16
TypeScript Life Cycle 16


5
Chapter 2 Visual Studio 18
Visual Studio Extension 18
Pre-Build Event 19
Trying it Out 20
Chapter 3 Type Safety 21

Static, Dynamic, and Optional Types 21
Inferred Types 21
Built-in Types 25
Custom Types 27
Advanced Type Declarations 27
Type Inference Mechanism 29
Variables and Parameters 29
Functions 30
Contextual Typing 30
Widened Types 31
When to Use Types 31
Chapter 4 Creating New Modules 32
Modules 32
Declaring a Module 32
Adding a Class to a Module 33
Interfaces, Classes, and Functions 35
Private Functions 35
Static Functions 37
Default Parameters 38
Optional Parameters 39
Rest Parameters 40
Function Overloads 40



6
Constructors 42
Interfaces 43
Multiple Interfaces 44
Duck Typing 44

Inheritance and Polymorphism 45
Multiple Inheritance 46
Using instanceof 47
Chapter Summary 48
Chapter 5 Loading Modules 49
Bundling 49
Module Declaration Style 49
Module Referencing Style 50
Script Loading Style 50
Summary 51
CommonJS Modules 51
Module Declaration Style 52
Module Referencing Style 52
Script Loading Style 52
Summary 53
AMD Modules 53
Module Declaration Style 53
Module Referencing Style 53
Script Loading Style 54
Chapter Summary 54
Chapter 6 Working with Existing JavaScript 55
Creating Ambient Declarations 55
Porting JavaScript to TypeScript 57


7
Transferring Design Patterns 59
Chapter 7 Unit Testing with TypeScript 60
Testing with tsUnit 60
Setting it Up 60

Code under Test 60
Writing a tsUnit Test 61
Running the Test 63
Test Composition 65
Test Context Assertions 66
Test Doubles 68
Lightweight Fakes 70
Running Tests in Visual Studio 71
Unit Test Project 71
Referencing the Script Files 74
Adjusting the TypeScript Test 75
Creating the Unit Test 76
Testing with a JavaScript Framework 78
Summary 79
Appendix A: Alternative Development Tools 80
Appendix B: TypeScript Command Line 81
Appendix C: External Resources 82




8
The Story behind the Succinctly Series
of Books
Daniel Jebaraj, Vice President
Syncfusion, Inc.
taying on the cutting edge
As many of you may know, Syncfusion is a provider of software components for the
Microsoft platform. This puts us in the exciting but challenging position of always
being on the cutting edge.

Whenever platforms or tools are shipping out of Microsoft, which seems to be about
every other week these days, we have to educate ourselves, quickly.
Information is plentiful but harder to digest
In reality, this translates into a lot of book orders, blog searches, and Twitter scans.
While more information is becoming available on the Internet and more and more books are
being published, even on topics that are relatively new, one aspect that continues to inhibit us is
the inability to find concise technology overview books.
We are usually faced with two options: read several 500+ page books or scour the web for
relevant blog posts and other articles. Just as everyone else who has a job to do and customers
to serve, we find this quite frustrating.
The Succinctly series
This frustration translated into a deep desire to produce a series of concise technical books that
would be targeted at developers working on the Microsoft platform.
We firmly believe, given the background knowledge such developers have, that most topics can
be translated into books that are between 50 and 100 pages.
This is exactly what we resolved to accomplish with the Succinctly series. Isn’t everything
wonderful born out of a deep desire to change things for the better?
The best authors, the best content
Each author was carefully chosen from a pool of talented experts who shared our vision. The
book you now hold in your hands, and the others available in this series, are a result of the
authors’ tireless work. You will find original content that is guaranteed to get you up and running
in about the time it takes to drink a few cups of coffee.
S


9
Free forever
Syncfusion will be working to produce books on several topics. The books will always be free.
Any updates we publish will also be free.
Free? What is the catch?

There is no catch here. Syncfusion has a vested interest in this effort.
As a component vendor, our unique claim has always been that we offer deeper and broader
frameworks than anyone else on the market. Developer education greatly helps us market and
sell against competing vendors who promise to “enable AJAX support with one click,” or “turn
the moon to cheese!”
Let us know what you think
If you have any topics of interest, thoughts, or feedback, please feel free to send them to us at

We sincerely hope you enjoy reading this book and that it helps you better understand the topic
of study. Thank you for reading.










Please follow us on Twitter and “Like” us on Facebook to help us spread the
word about the Succinctly series!




10
About the Author
Steve Fenton is an Agile .NET developer with a keen interest in the web stack. He has been
creating business applications since 1997 and writing web applications since 2001. He is

currently keeping an eye on emerging standards and techniques for web development and was
an early adopter of the HTML 5 standards, releasing his first HTML 5 website in 2009.
Steve is well versed in JavaScript and has dabbled with alternatives such as Flash, Silverlight,
CoffeeScript, and Dart, but always preferred writing raw JavaScript—until he tried TypeScript in
2012.
In his spare time, Steve attends conferences, runs brown-bag learning lunches, reads books in
his local coffee shop, and attends ice hockey matches.
TypeScript is a trademark of Microsoft Corporation.


11
Introduction
Whenever the word JavaScript is mentioned to a room full of .NET developers, there are visible
shudders and uncomfortable fidgeting at the prospect of writing anything in such a sloppy
language. I actually love JavaScript, partly because it was the first curly-braced language that I
used, but also because I have learned to use it an appropriate way. However, I can understand
the reasons for its lack of popularity amongst the .NET community. If you spend most of your
time writing code in C#, VB.NET, or F#, the prospect of using a language that lacks sensible
autocompletion, type checking, and object-orientation is not a pleasant one—and this is where
TypeScript fits perfectly into the tool belt of a .NET programmer.
Is TypeScript the Answer?
There are no golden bullets in the world of software development. What is certain is that
JavaScript is one of the most widely adopted languages on Earth, and it isn’t likely to be
disappearing any time soon, especially given its recent emergence as a high-volume web-
server language under the Node.js moniker.
TypeScript eases the pain of JavaScript development by adding some of the features that .NET
developers take for granted. It is already smoothly integrated into Visual Studio, which makes it
easy to use without switching development tools.
I envisage a future where developers don’t need to write boilerplate JavaScript, not because
they are using a framework that includes everything they might need to use, but because they

can compose a number of small and reusable modules that take care of specific areas, like
AJAX, SVG, and Canvas.
Who is This Book For?
I have written this book primarily for professional .NET developers. TypeScript isn’t exclusively
for the .NET domain, as Microsoft has released the language under an open source license and
there are plug-ins for Sublime Text, Vim, Emacs, and WebStorm, as well as Visual Studio,
which has a fully featured extension. You don’t have to be a JavaScript expert to read this book,
but if you would like to learn more about it, you can download JavaScript Succinctly by Cody
Lindley from the Syncfusion Technology Resource Portal:




12
What is Missing?
Currently, TypeScript is available as a preview and the language specification is labeled version
0.9. It is likely that the list of features will grow as the TypeScript compiler becomes smarter.
Some of the current features haven’t been finalized and are likely to change, and there are
further planned features that haven’t yet been written. I have tried to make it clear where a
feature is experimental or likely to change, as well as noting alternatives to features that can
harm the readability of your code.
Code Samples
All of the examples in this book were created in Visual Studio 2012 using the freely available
TypeScript for Visual Studio 2012 extension. Many of the examples can also be tested in the
online TypeScript Playground at
In this book, the code samples are shown in code blocks such as the following example.
Sample1.ts Code Samples
The code samples in this book can be downloaded from

Notes

There are notes that highlight particularly interesting information about a language feature,
including potential pitfalls you will want to avoid.

Note: An interesting note about TypeScript.


function log(message) {
if (typeof window.console !== 'undefined') {
window.console.log(message);
}
}


13
Chapter 1 Concepts in TypeScript
Code organization
I will begin by drawing some parallels between .NET and TypeScript in respect to code
organization and language features. In some cases the conventions are nearly identical, but
there are also some interesting differences in both the naming conventions and the meaning of
the various components used to compose your application.
Figure 1 demonstrates the structure of a TypeScript program, which is organized into a number
of modules, each containing interfaces, classes, and variables. Each module should group
related classes together and should have minimal dependencies on other modules in your
program. Although you can create multidirectional dependencies and circular dependencies in
TypeScript, I recommend that you avoid doing so, as it will make your program harder to
maintain.
This program structure allows you to put your object-oriented programming skills into practice
and makes it easy to use common design patterns to organize your program.
I will use the TypeScript naming conventions throughout this book, but feel free to read method
when I use the term function, for example, if that is what you are more used to.


Figure 1: A TypeScript program




14
TypeScript Glossary
Program
A TypeScript program is a collection of source files. Most of these source files will contain your
code implementation, but they can also contain declarations that add static types to external
code. I will talk about writing you own code in Chapter 4, "Creating new modules," and
consuming existing code and third-party libraries in Chapter 6, "Working with existing
JavaScript."
You can think of your program as both the TypeScript .ts files and the compiled JavaScript .js
files.
Module
TypeScript modules are similar to .NET namespaces, and can contain a number of classes and
interfaces. The structure of your modules can vary from very flat structures to highly nested
ones depending on the kind of program you are writing.
Interface
Interfaces in TypeScript work exactly like .NET interfaces, allowing the development tools and
the compiler to emit errors if a class fails to implement an interface correctly. Because the
interface exists solely for the benefit of the design-time tools and the compiler, no JavaScript
code is generated from a TypeScript interface.
A TypeScript interface can extend multiple interfaces.
Class
A TypeScript class is similar to a .NET class and can contain functions and variables with
varying levels of visibility. In TypeScript you can use public and private visibility keywords
on functions and variables. A TypeScript class can extend one class and implement multiple

interfaces.
Function
A TypeScript function is like a .NET method, accepting arguments and returning a typed value
or void. This is where the real logic will live in your program.


15
Variable
In TypeScript all properties and fields are variables, but with optional typing. By default, these
variables behave in a similar manner to those declared in .NET using the var keyword, as the
compiler will attempt to infer the type and then treat the variable as statically typed. In cases
where the type cannot be inferred, the compiler doesn’t show an error as it would in .NET, but
instead treats the variable as a dynamic type, which in TypeScript is indicated with the any
keyword. I will discuss this in more detail in Chapter 3, "Type safety."
Enumeration
Enumerations in TypeScript are similar to .NET enumerations. The experimental implementation
in version 0.8 of TypeScript has been amended slightly in version 0.9.
Scope
Because functions, classes, and modules are compiled into various flavors of JavaScript
functions, everything nested within them is locally scoped, and will enjoy the benefits of
JavaScript’s lexical scoping. This means a nested function has access to its own variables and
also the variables in the outer function. If no variable exists in the local scope, the JavaScript
runtime walks up the chain to find the variable in the outer function, and if no variable exists
there, it continues to the next level. This continues right up until JavaScript checks the global
scope.
Compilation
TypeScript is converted into JavaScript at compile time. JavaScript is an implementation of the
ECMAScript standard, and it isn’t the only one–ActionScript is another well-known language
based on the ECMAScript standard. There are three versions of ECMAScript that you will come
across when dealing with TypeScript.

ECMAScript 3
ECMAScript 3 was published in 1999, and it is the version supported in most browsers. When
TypeScript compiles into JavaScript, it uses the ECMAScript 3 standard by default. A very small
number of features are unavailable in TypeScript when targeting ECMAScript 3, such as
property getters and setters, but it offers the widest possible support for your program.
If you try to use a feature that isn’t available in the version of ECMAScript you are targeting, the
compiler will warn you to either avoid the feature or change the target version. I have included
instructions on how to target ECMAScript 5 in Chapter 2, "Visual Studio."



16
ECMAScript 5
ECMAScript 5 was published in 2009 and is supported in all modern browsers. You can instruct
the TypeScript compiler to target ECMAScript 5, which makes additional language features
available, but your program may encounter problems in older browsers. The following browsers
support all of the important features of ECMAScript 5; older versions of these browsers have
only partial support:
 Internet Explorer 9 and above.
 Firefox 4 and above.
 Opera 12 and above.
 Safari 5.1 and above.
 Chrome 7 and above.
ECMAScript 6
ECMAScript 6, also known as ECMAScript Harmony, is currently being drafted and has
experimental support in some of the latest browsers. This version is interesting, because it will
make modules and classes part of the JavaScript language. TypeScript gives you immediate
access to these proposed new features in practically all browsers. At some point in the future
you will be able to target the ECMAScript 6 standard from TypeScript, which will mean the
compiled JavaScript will more closely match your TypeScript code.

There is currently no release date planned for ECMAScript 6, and it doesn’t support all of the
concepts in the TypeScript language.
TypeScript Life Cycle
The TypeScript life cycle consists of three distinct stages. When you are writing TypeScript
code, you are participating in the design time stage along with any development tools you are
using. The compiler represents the second stage, converting TypeScript into JavaScript, and
raising errors and warnings it discovers. The final stage involves the runtime executing the
generated JavaScript.


17

Figure 2: TypeScript life cycle





18
Chapter 2 Visual Studio
This chapter describes how to set up Visual Studio 2012 for TypeScript. If you are using a
different development environment, you can skip this chapter. There are more details on using
TypeScript with other tools in Appendix A: Alternative Development Tools.
Visual Studio Extension
The first task is to download and install the TypeScript for Visual Studio 2012 plug-in from the
TypeScript language website at
This will add TypeScript language support as well as new project and file templates. You can
add TypeScript files to an existing project, but for the examples in this book you can simply
create a new project using the HTML Application with TypeScript template, which can be found
under the Visual C# Templates—this is something of a misnomer as the project won’t contain

C# or VB.NET.

Figure 3: New project types in Visual Studio


19
The TypeScript file template can be accessed via the Add New Item menu, and also appears as
a shortcut in the project context menu once you have added a TypeScript file to your project.
The default template contains an example interface, module, and class, but you can change this
template by navigating to the extensions zip file and editing the file named file.ts. The part of the
path shown in bold is likely to be different on your computer, but you can perform a search for
f.zip in the Extensions folder if you get stuck.
C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\
msfz1qy5.oca\~IC\IT\CSharp\1033\f.zip


Figure 4: Add TypeScript file shortcut
The plug-in also installs the TypeScript compiler, which can be used from the command line,
Visual Studio, and your build server.
C:\Program Files (x86)\Microsoft SDKs\TypeScript\tsc.exe
You can also use the Web Essentials 2012 extension, which adds side-by-side editing to Visual
Studio.
Pre-Build Event
If you are using a project with automatic TypeScript support, such as the HTML Application with
TypeScript project template, all of your TypeScript files will automatically be compiled into a
paired JavaScript file each time you build the project, or each time a file is saved if you are
using the latest version of the TypeScript Visual Studio extension.
If you want to add TypeScript to an existing project, for example, to an ASP.NET MVC Web
Application, you can add the required sections to your project file. To edit your project file, select
Unload from the context menu. Then re-open the context menu and select Edit.




20

Figure 5: Project context menu
There are two sections to add. The ItemGroup element defines the files to be compiled
(everything in your project with a .ts file extension). The Target element contains the build step
that runs the TypeScript compiler against these files. The exact entries are shown below and
can be pasted directly into your project.
If you want the compiler to target ECMAScript 5, you can adjust this example to include the
target flag, as shown in the following example. You should only use this if you are certain that
you don’t need to support older browsers.
Trying it Out
Once you have performed these steps, Visual Studio is ready to use. Build your solution to
make sure that there are no problems with any changes you have made to the project file.
<ItemGroup>
<TypeScriptCompile Include="$(ProjectDir)\**\*.ts" />
</ItemGroup>
<Target Name="BeforeBuild">
<Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript\tsc&quot;
@(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
</Target>
<ItemGroup>
<TypeScriptCompile Include="$(ProjectDir)\**\*.ts" />
</ItemGroup>
<Target Name="BeforeBuild">
<Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript\tsc&quot;
target ES5 @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
</Target>



21
Chapter 3 Type Safety
Static, Dynamic, and Optional Types
A statically typed language gives you compile-time checking for type safety. This doesn’t mean
you have to specify all types explicitly, as a smart compiler can infer the types in many cases.
TypeScript is no exception and the compiler will intelligently determine types for you even if you
don’t explicitly declare the types in your code.
TypeScript is referred to as optionally statically typed, which means you can ask the compiler to
ignore the type of a variable if you want to take advantage of dynamic typing in a particular
circumstance. This mix of static and dynamic typing is already present in .NET; for example, C#
is statically typed but allows dynamic types to be declared with the dynamic keyword.
As well as compile-type checking, the language constructs allow static analysis that makes it
possible for development tools to highlight errors in your code at design time without the need
for compilation.
Throughout this chapter, I will give practical examples that will show you how to take advantage
of TypeScript’s static analysis and compilation.
Inferred Types
Before I start introducing the TypeScript language features, here is a plain and simple
JavaScript logging function. This is a common paradigm in JavaScript development that checks
for the presence of a console before attempting to write a message to it. If you don’t perform this
check, calling the console results in an error when one isn’t attached.
Sample2.ts Logging Function
function log(message) {
if (typeof window.console !== 'undefined') {
window.console.log(message);
}
}


var testLog = "Hello world";

log(testLog);



22

Even though this example is plain JavaScript, the TypeScript compiler is smart enough to infer
that testLog is a string. If you hover over the variables and functions in your development
environment you’ll see the following tooltips.
Table 1: Types in Sample2.ts
Name
Tooltip
log
(message: any) => void
message
any
window.console
Console
testLog
string
There are several benefits to this type knowledge when it comes to writing your code. Firstly, if
you try to assign a value to testLog that isn’t a string type, you will get a design-time warning
and a compilation error.
Because TypeScript is aware of the types, development tools are able to supply more precise
autocompletion than they can for JavaScript. For example, if you didn’t know the type of
testLog, you would have to supply an autocompletion list that either covered all possible
suggestions for all types or no suggestions at all. Because TypeScript knows the type is
string, the autocompletion can contain just the properties and operations relevant to a string.


Figure 6: Precise autocompletion


23
This is a demonstration of type inference, where the tools work out the types based on the
values you assign in code. It isn’t always possible or desirable to infer the types automatically
like this, and that is the reason the message parameter has the dynamic any type, which means
it is not statically typed. You could argue that based on the calling code, which always passes a
string, it is possible to infer that message is also of type string. The problem with this kind of
inference is that it relies on all calling code being available at compilation time, which is almost
certainly not the case–so rather than make a potentially dangerous assumption, TypeScript
uses the any type.
You don’t have to rely on type inference in your code, and you can use type declarations to tell
the compiler the intended type of a variable, function, or parameter in cases where it cannot
work it out. In the logging example, you only need to tell TypeScript the type of the message
parameter in order for everything to be statically typed. To declare a type, append a colon
followed by the type name; in this case, you would decorate the message parameter with a :
string declaration
Sample3.ts Typed Parameters
Now when you view the tooltips for this code, you will see that everything is statically typed and
the dynamic any keyword has been replaced in both the log function signature and the
message parameter:
Table 2: Types in Sample3.ts
Name
Tooltip
log
(message: string) => void
message
string

window.console
Console
function log(message: string) {
if (typeof window.console !== 'undefined') {
window.console.log(message);
}
}

var testLog = "Hello world";

log(testLog);



24
Name
Tooltip
testLog
string

You can test the static typing by calling the log method with different values. Your development
tools should highlight the erroneous calls that fail to pass a string argument. This will work in
all cases where there is a type, whether it is inferred by the compiler or explicitly declared in
your code.
Sample4.ts Function Call Type Checking
The level of type declarations you add yourself is a matter of taste; you could explicitly declare
the types everywhere in your code, but I personally find the resulting code too verbose, and in
many cases adding a type declaration is redundant when the type is already obvious. The next
two examples compare two approaches to help illustrate this subject. The first is an entirely
explicit version of the logging code and the second applies a more pragmatic level of

declarations.
Sample5.ts Entirely Explicit Types
// allowed
log("Hello world");

// not allowed
log(1);
log(true);
log({ 'key': 'value' });
function log(message: string): void {
if (typeof window.console !== 'undefined') {
window.console.log(message);
}
}

var testLog: string = "Hello world";

log(testLog);


25
Sample6.ts Pragmatic Explicit Types
In the second example, I explicitly state the type for any variable or parameter that cannot be
inferred by the compiler and additionally make the return type explicit for functions, which I find
makes the function more readable. I haven’t specified the type for the testLog variable as it is
obvious that it is a string because it is initialized with a string literal. I will go into more detail in
the section When to Use Types at the end of this chapter.
Built-in Types
TypeScript has five built-in primitive types as well as the dynamic any type and the void return
type. The any type can have any value assigned to it, and its type can be changed at runtime,

so it could be initialized with a string and later overwritten with a number, or even a custom
type. The void return type can only be used to declare that a function does not return a value.
The following list contains the five built-in primitive types.
Table 3: Primitive Types
Name
Tooltip
number
The number type is equivalent to
the primitive JavaScript number
type, which represents double-
precision 64-bit floating-point
values. If you are used to the
distinction of integer types and
non-whole numbers, there is no
such distinction in TypeScript.
boolean
The boolean type represents a
value that is either true or false.
function log(message: string): void {
if (typeof window.console !== 'undefined') {
window.console.log(message);
}
}

var testLog = 'Hello world';

log(testLog);

×