Create Your First TypeScript File
Write your first .ts file from scratch. Add type annotations, compile with tsc, run the JavaScript output, and understand what changed.
Creating a TypeScript file is the same as creating a JavaScript file, with one difference: you add type annotations to tell the compiler what shape your data should have. The file extension is .ts instead of .js.
Here is the complete workflow: write the file, compile it, run it. Let's do all three.
Write Your First .ts File
Every TypeScript file starts as a plain JavaScript file with type annotations added on top. Create a new file called greeting.ts in an empty folder and add this function, which picks a greeting based on the hour of day:
function createGreeting(name: string, hour: number): string {
if (hour < 12) {
return `Good morning, ${name}!`;
} else if (hour < 18) {
return `Good afternoon, ${name}!`;
} else {
return `Good evening, ${name}!`;
}
}This is plain JavaScript with three type annotations added:
name: string-- the first parameter must be a string.hour: number-- the second parameter must be a number.: stringafter the parentheses -- the function must return a string.
The rest of the code is standard JavaScript, and the types are additions, not replacements. Call the function and print the result at the bottom of the same file:
const message = createGreeting("Alex", 10);
console.log(message);Save the file. You now have a complete TypeScript file ready to compile.
Compile the File
Open your terminal in the same folder as greeting.ts. If you have not installed TypeScript yet, install it globally first, then compile the file:
npm install -g typescript
tsc greeting.tsCompiling reads greeting.ts, checks every type annotation, and writes a new file called greeting.js next to it. Open that file to see the function with its types removed:
function createGreeting(name, hour) {
if (hour < 12) {
return `Good morning, ${name}!`;
}
else if (hour < 18) {
return `Good afternoon, ${name}!`;
}
else {
return `Good evening, ${name}!`;
}
}Every type annotation is gone. The string and number annotations were used only for checking, then stripped. Everything else, including the template literals, stays exactly as written, because the default target in modern TypeScript already emits a recent JavaScript version. The call at the bottom of the file is untouched too:
const message = createGreeting("Alex", 10);
console.log(message);Older syntax like var and string concatenation only shows up if you explicitly set an older target in a tsconfig.json, which later articles cover.
Run the JavaScript Output
Run the compiled file directly with Node.js, the same way you would run any JavaScript file:
node greeting.jsThis is plain JavaScript now, so Node.js runs it exactly like any other script, with no TypeScript-specific tooling involved, and prints the greeting straight to the terminal:
Good morning, Alex!The program works the same as it would have in plain JavaScript. The difference is that TypeScript checked your work before any of this ran.
See What Happens with a Type Error
Now add a mistake. Change the last two lines of greeting.ts so the second argument is a string instead of a number:
const message = createGreeting("Alex", "ten"); // "ten" is a string, not a number
console.log(message);Save the file and compile it again the same way as before. This time the compiler stops you before you can run anything broken:
tsc greeting.tsCompiling again immediately surfaces the problem. You get this exact error, pointing at the file, the line, and the argument that does not match:
greeting.ts:9:43 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.The compiler tells you the exact file, line, column, and what went wrong. It knows hour expects a number and you passed a string. The error appears before you run anything.
In JavaScript, this same code would run without complaint and silently produce the wrong result:
Good evening, Alex!JavaScript compares "ten" < 12 by coercing the string to a number, and Number("ten") is NaN. Every comparison against NaN is false, so both the if and else if checks fail and the code falls through to the else branch. You would get the wrong greeting with no error message. TypeScript catches the mismatch at compile time instead.
Add More Type Annotations
Variables can have types too. Expand greeting.ts with typed variables:
let userName: string = "Alex";
let userAge: number = 28;
let isLoggedIn: boolean = true;
function getProfile(name: string, age: number, active: boolean): string {
const status = active ? "online" : "offline";
return `${name}, age ${age}, is ${status}.`;
}
console.log(getProfile(userName, userAge, isLoggedIn));The compiler now has more to check: the types of userName, userAge, isLoggedIn, and the return value of getProfile. Compile and run this expanded file in one step, the same way as before:
tsc greeting.ts && node greeting.jsChaining the two commands with && means the second only runs if the first succeeds, so a type error stops you before broken code executes. The terminal prints:
Alex, age 28, is online.If you later assign a number to userName or pass a string where userAge is expected, the compiler catches it immediately, the same way it caught the earlier mistake.
The Pattern for Every TypeScript File
Every TypeScript file you write follows the same pattern:
- Write JavaScript that solves a problem.
- Add type annotations on function parameters, return values, and important variables.
- Compile with
tscto check for errors. - Fix any type errors the compiler reports.
- Run the compiled JavaScript with Node.js.
The types are optional. You can add as few or as many as you want. Start with function parameters and return types, since those are where most bugs hide. Add types to variables later when the extra safety is useful.
For a deeper look at the compilation step, see compile TypeScript to JavaScript. To understand what compiler errors mean and how to fix them, read read TypeScript compiler errors.
Rune AI
Key Insights
- TypeScript files use the
.tsextension and contain JavaScript plus optional type annotations. - Compile with
tsc filename.tsto produce a.jsfile, then run it with Node.js. - Type annotations are stripped during compilation. They never appear in the JavaScript output.
- Start with simple annotations like
: stringand: numberon variables and function parameters. - Every valid
.jsfile is also a valid.tsfile. You can adopt TypeScript one file at a time.
Frequently Asked Questions
What file extension does TypeScript use?
Can I rename a .js file to .ts and expect it to work?
Do I need a tsconfig.json to create a TypeScript file?
Conclusion
Your first TypeScript file is three steps: write a .ts file with a type annotation, compile it with tsc, and run the output with Node.js. The type annotation you added is gone in the JavaScript output, but it caught a potential bug before your code ever ran. That is the core TypeScript workflow, and everything else builds on it.
More in this topic
TypeScript Compiler Explained
The TypeScript compiler (tsc) turns .ts files into .js files while checking types. Learn what it does, how to use it, and how it fits your workflow.
Set Up ESLint for TypeScript
Install and configure ESLint with typescript-eslint to catch bugs and enforce consistent code style in your TypeScript project.
Pick Utility Type in TypeScript
Pick creates a new type by selecting only the properties you name from an existing type. Use it to build focused types for specific views, API responses, or function parameters.