{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/typescript-in-5-minutes-oop.html","result":{"data":{"allSitePage":{"nodes":[{"path":"/dev-404-page/"},{"path":"/docs/handbook/advanced-types.html"},{"path":"/docs/handbook/basic-types.html"},{"path":"/docs/handbook/classes.html"},{"path":"/docs/handbook/compiler-options-in-msbuild.html"},{"path":"/docs/handbook/compiler-options.html"},{"path":"/docs/handbook/configuring-watch.html"},{"path":"/docs/handbook/declaration-merging.html"},{"path":"/docs/handbook/decorators.html"},{"path":"/docs/handbook/enums.html"},{"path":"/docs/handbook/functions.html"},{"path":"/docs/handbook/generics.html"},{"path":"/docs/handbook/integrating-with-build-tools.html"},{"path":"/docs/handbook/interfaces.html"},{"path":"/docs/handbook/iterators-and-generators.html"},{"path":"/docs/handbook/jsdoc-supported-types.html"},{"path":"/docs/handbook/jsx.html"},{"path":"/docs/handbook/literal-types.html"},{"path":"/docs/handbook/mixins.html"},{"path":"/docs/handbook/module-resolution.html"},{"path":"/docs/handbook/modules.html"},{"path":"/docs/handbook/namespaces-and-modules.html"},{"path":"/docs/handbook/namespaces.html"},{"path":"/docs/handbook/nightly-builds.html"},{"path":"/docs/handbook/project-references.html"},{"path":"/docs/handbook/symbols.html"},{"path":"/docs/handbook/"},{"path":"/docs/handbook/triple-slash-directives.html"},{"path":"/docs/handbook/type-checking-javascript-files.html"},{"path":"/docs/handbook/type-compatibility.html"},{"path":"/docs/handbook/type-inference.html"},{"path":"/docs/handbook/unions-and-intersections.html"},{"path":"/docs/handbook/utility-types.html"},{"path":"/docs/handbook/variable-declarations.html"},{"path":"/docs/handbook/writing-declaration-files.html"},{"path":"/docs/handbook/declaration-files/by-example.html"},{"path":"/docs/handbook/declaration-files/consumption.html"},{"path":"/docs/handbook/declaration-files/deep-dive.html"},{"path":"/docs/handbook/declaration-files/do-s-and-don-ts.html"},{"path":"/docs/handbook/declaration-files/introduction.html"},{"path":"/docs/handbook/declaration-files/library-structures.html"},{"path":"/docs/handbook/declaration-files/publishing.html"},{"path":"/docs/handbook/declaration-files/templates.html"},{"path":"/docs/handbook/release-notes/typescript-1-1.html"},{"path":"/docs/handbook/release-notes/typescript-1-3.html"},{"path":"/docs/handbook/release-notes/typescript-1-4.html"},{"path":"/docs/handbook/release-notes/typescript-1-5.html"},{"path":"/docs/handbook/release-notes/typescript-1-6.html"},{"path":"/docs/handbook/release-notes/typescript-1-7.html"},{"path":"/docs/handbook/release-notes/typescript-1-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-0.html"},{"path":"/docs/handbook/release-notes/typescript-2-2.html"},{"path":"/docs/handbook/release-notes/typescript-2-1.html"},{"path":"/docs/handbook/release-notes/typescript-2-3.html"},{"path":"/docs/handbook/release-notes/typescript-2-4.html"},{"path":"/docs/handbook/release-notes/typescript-2-5.html"},{"path":"/docs/handbook/release-notes/typescript-2-6.html"},{"path":"/docs/handbook/release-notes/typescript-2-7.html"},{"path":"/docs/handbook/release-notes/typescript-2-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-9.html"},{"path":"/docs/handbook/release-notes/typescript-3-0.html"},{"path":"/docs/handbook/release-notes/typescript-3-1.html"},{"path":"/docs/handbook/release-notes/typescript-3-2.html"},{"path":"/docs/handbook/release-notes/typescript-3-3.html"},{"path":"/docs/handbook/release-notes/typescript-3-4.html"},{"path":"/docs/handbook/release-notes/typescript-3-5.html"},{"path":"/docs/handbook/release-notes/typescript-3-6.html"},{"path":"/docs/handbook/release-notes/typescript-3-7.html"},{"path":"/docs/handbook/release-notes/typescript-3-8.html"},{"path":"/docs/handbook/asp-net-core.html"},{"path":"/docs/handbook/angular.html"},{"path":"/docs/handbook/dom-manipulation.html"},{"path":"/docs/handbook/gulp.html"},{"path":"/docs/handbook/migrating-from-javascript.html"},{"path":"/docs/handbook/react-&-webpack.html"},{"path":"/docs/handbook/react.html"},{"path":"/docs/handbook/typescript-in-5-minutes-func.html"},{"path":"/docs/handbook/typescript-in-5-minutes.html"},{"path":"/docs/handbook/typescript-in-5-minutes-oop.html"},{"path":"/docs/handbook/typescript-from-scratch.html"},{"path":"/docs/handbook/typescript-tooling-in-5-minutes.html"},{"path":"/docs/handbook/tsconfig-json.html"},{"path":"/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-class-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-function-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-d-ts.html"},{"path":"/docs/handbook/release-notes/overview.html"},{"path":"/tsconfig"},{"path":"/en/tsconfig"},{"path":"/ja/tsconfig"},{"path":"/vo/tsconfig"},{"path":"/play"},{"path":"/en/play"},{"path":"/es/play"},{"path":"/vo/play"},{"path":"/zh/play"},{"path":"/ja/play"},{"path":"/play/3-7/fixits/big-number-literals.ts"},{"path":"/play/3-7/fixits/const-to-let.ts"},{"path":"/play/3-7/fixits/infer-from-usage-changes.ts"},{"path":"/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/play/3-7/syntax-and-messaging/nullish-coalescing.ts"},{"path":"/play/3-7/syntax-and-messaging/optional-chaining.ts"},{"path":"/play/3-7/types-and-code-flow/assertion-functions.ts"},{"path":"/play/3-7/types-and-code-flow/recursive-type-references.ts"},{"path":"/play/3-7/types-and-code-flow/uncalled-function-checks.ts"},{"path":"/play/3-8/breaking-changes/checking-unions-with-index-signatures.ts"},{"path":"/play/3-8/jsdoc-improvements/accessibility-modifiers.js"},{"path":"/play/3-8/syntax-and-messaging/export-modules-from.ts"},{"path":"/play/3-8/syntax-and-messaging/private-class-fields.ts"},{"path":"/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/play/javascript/external-apis/typescript-with-node.js"},{"path":"/play/javascript/external-apis/typescript-with-web.js"},{"path":"/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/play/javascript/helping-with-javascript/errors.ts"},{"path":"/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/play/javascript/javascript-essentials/functions.ts"},{"path":"/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/play/javascript/modern-javascript/async-await.ts"},{"path":"/play/javascript/modern-javascript/immutability.ts"},{"path":"/play/javascript/modern-javascript/import-export.ts"},{"path":"/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/play/javascript/working-with-classes/classes-101.ts"},{"path":"/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/play/javascript/working-with-classes/mixins.ts"},{"path":"/play/javascript/working-with-classes/this.ts"},{"path":"/play/playground/config/javascript-playgrounds.js"},{"path":"/play/playground/config/new-compiler-defaults.ts"},{"path":"/play/playground/language/automatic-type-acquisition.ts"},{"path":"/play/playground/language/fixits.ts"},{"path":"/play/playground/tooling/mobile-support.ts"},{"path":"/play/playground/tooling/sharable-urls.ts"},{"path":"/play/playground/tooling/typescript-versions.ts"},{"path":"/play/typescript/language/soundness.ts"},{"path":"/play/typescript/language/structural-typing.ts"},{"path":"/play/typescript/language/type-guards.ts"},{"path":"/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/play/typescript/language-extensions/enums.ts"},{"path":"/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/play/typescript/meta-types/conditional-types.ts"},{"path":"/play/typescript/meta-types/discriminate-types.ts"},{"path":"/play/typescript/meta-types/indexed-types.ts"},{"path":"/play/typescript/meta-types/mapped-types.ts"},{"path":"/play/typescript/primitives/any.ts"},{"path":"/play/typescript/primitives/literals.ts"},{"path":"/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/play/typescript/primitives/unknown-and-never.ts"},{"path":"/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/play/typescript/type-primitives/nullable-types.ts"},{"path":"/play/typescript/type-primitives/tuples.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-node.js"},{"path":"/es/play/javascript/external-apis/typescript-with-web.js"},{"path":"/es/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/es/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/es/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/es/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/es/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/es/play/typescript/type-primitives/nullable-types.ts"},{"path":"/es/play/typescript/type-primitives/tuples.ts"},{"path":"/ja/play/typescript/language-extensions/enums.ts"},{"path":"/ja/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/ja/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/ja/play/typescript/primitives/any.ts"},{"path":"/ja/play/typescript/primitives/literals.ts"},{"path":"/ja/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/ja/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/vo/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/vo/play/javascript/javascript-essentials/functions.ts"},{"path":"/vo/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/vo/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-node.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-web.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/zh/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/zh/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/zh/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/zh/play/javascript/helping-with-javascript/errors.ts"},{"path":"/zh/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/zh/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/zh/play/javascript/javascript-essentials/functions.ts"},{"path":"/zh/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/zh/play/javascript/modern-javascript/import-export.ts"},{"path":"/zh/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/zh/play/javascript/working-with-classes/classes-101.ts"},{"path":"/zh/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/zh/play/javascript/working-with-classes/mixins.ts"},{"path":"/zh/play/javascript/working-with-classes/this.ts"},{"path":"/zh/play/playground/config/javascript-playgrounds.js"},{"path":"/zh/play/playground/config/new-compiler-defaults.ts"},{"path":"/zh/play/playground/language/automatic-type-acquisition.ts"},{"path":"/zh/play/playground/language/fixits.ts"},{"path":"/zh/play/playground/tooling/mobile-support.ts"},{"path":"/zh/play/playground/tooling/sharable-urls.ts"},{"path":"/zh/play/playground/tooling/typescript-versions.ts"},{"path":"/zh/play/typescript/language/soundness.ts"},{"path":"/zh/play/typescript/language/structural-typing.ts"},{"path":"/zh/play/typescript/language/type-guards.ts"},{"path":"/zh/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/zh/play/typescript/language-extensions/enums.ts"},{"path":"/zh/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/zh/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/zh/play/typescript/meta-types/conditional-types.ts"},{"path":"/zh/play/typescript/meta-types/discriminate-types.ts"},{"path":"/zh/play/typescript/meta-types/indexed-types.ts"},{"path":"/zh/play/typescript/meta-types/mapped-types.ts"},{"path":"/zh/play/typescript/primitives/any.ts"},{"path":"/zh/play/typescript/primitives/literals.ts"},{"path":"/zh/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/zh/play/typescript/primitives/unknown-and-never.ts"},{"path":"/zh/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/zh/play/typescript/type-primitives/nullable-types.ts"},{"path":"/zh/play/typescript/type-primitives/tuples.ts"},{"path":"/zh/play/javascript/modern-javascript/immutability.ts"},{"path":"/zh/play/javascript/modern-javascript/async-await.ts"},{"path":"/zh/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/community"},{"path":"/es/community"},{"path":"/ja/community"},{"path":"/vo/community"},{"path":"/zh/community"},{"path":"/download"},{"path":"/es/download"},{"path":"/ja/download"},{"path":"/vo/download"},{"path":"/zh/download"},{"path":"/empty"},{"path":"/es/empty"},{"path":"/ja/empty"},{"path":"/vo/empty"},{"path":"/zh/empty"},{"path":"/"},{"path":"/es/"},{"path":"/ja/"},{"path":"/vo/"},{"path":"/zh/"},{"path":"/tools"},{"path":"/es/tools"},{"path":"/ja/tools"},{"path":"/vo/tools"},{"path":"/zh/tools"},{"path":"/why-create-typescript"},{"path":"/es/why-create-typescript"},{"path":"/ja/why-create-typescript"},{"path":"/vo/why-create-typescript"},{"path":"/zh/why-create-typescript"},{"path":"/docs/home"},{"path":"/es/docs/home"},{"path":"/ja/docs/home"},{"path":"/vo/docs/home"},{"path":"/zh/docs/home"},{"path":"/dev/playground-plugins/"},{"path":"/dev/sandbox/"},{"path":"/dev/twoslash/"},{"path":"/dev/typescript-vfs/"}]},"markdownRemark":{"id":"d864c061-9ca2-59a2-b63f-9ba16e6c3a08","excerpt":"TypeScript is a popular choice for programmers accustomed to other languages with static typing, such as C# and Java. TypeScript’s type system offers many of…","html":"<p>TypeScript is a popular choice for programmers accustomed to other languages with static typing, such as C# and Java.</p>\n<p>TypeScript’s type system offers many of the same benefits, such as better code completion, earlier detection of errors, and clearer communication between parts of your program.\nWhile TypeScript provides many familiar features for these developers, it’s worth stepping back to see how JavaScript (and therefore TypeScript) differ from traditional OOP languages.\nUnderstanding these differences will help you write better JavaScript code, and avoid common pitfalls that programmers who go straight from C#/Java to TypeScript may fall in to.</p>\n<h2 id=\"co-learning-javascript\" style=\"position:relative;\"><a href=\"#co-learning-javascript\" aria-label=\"co learning javascript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Co-learning JavaScript</h2>\n<p>If you’re familiar with JavaScript already 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.\nSome of the ways that TypeScript models types are quite different from Java or C#, and it’s important to keep these in mind when learning TypeScript.</p>\n<p>If you’re a Java or C# programmer that is new to JavaScript in general, we recommend learning a little bit of JavaScript <em>without</em> types first to understand JavaScript’s runtime behaviors.\nBecause TypeScript doesn’t change how your code <em>runs</em>, you’ll still have to learn how JavaScript works in order to write code that actually does something!</p>\n<p>It’s important to remember that TypeScript uses the same <em>runtime</em> as JavaScript, so any resources about how to accomplish specific runtime behavior (converting a string to a number, displaying an alert, writing a file to disk, etc.) will always apply equally well to TypeScript programs.\nDon’t limit yourself to TypeScript-specific resources!</p>\n<h2 id=\"rethinking-the-class\" style=\"position:relative;\"><a href=\"#rethinking-the-class\" aria-label=\"rethinking the class permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Rethinking the Class</h2>\n<p>C# and Java are what we might call <em>mandatory OOP</em> languages.\nIn these languages, the <em>class</em> is the basic unit of code organization, and also the basic container of all data <em>and</em> behavior at runtime.\nForcing all functionality and data to be held in classes can be a good domain model for some problems, but not every domain <em>needs</em> to be represented this way.</p>\n<h3 id=\"free-functions-and-data\" style=\"position:relative;\"><a href=\"#free-functions-and-data\" aria-label=\"free functions and data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Free Functions and Data</h3>\n<p>In JavaScript, functions can live anywhere, and data can be passed around freely without being inside a pre-defined <code>class</code> or <code>struct</code>.\nThis flexibility is extremely powerful.\n“Free” functions (those not associated with a class) working over data without an implied OOP hierarchy tends to be the preferred model for writing programs in JavaScript.</p>\n<h3 id=\"static-classes\" style=\"position:relative;\"><a href=\"#static-classes\" aria-label=\"static classes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Static Classes</h3>\n<p>Additionally, certain constructs from C# and Java such as singletons and static classes are unnecessary in TypeScript.</p>\n<h2 id=\"oop-in-typescript\" style=\"position:relative;\"><a href=\"#oop-in-typescript\" aria-label=\"oop in typescript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>OOP in TypeScript</h2>\n<p>That said, you can still use classes if you like!\nSome problems are well-suited to being solved by a traditional OOP hierarchy, and TypeScript’s support for JavaScript classes will make these models even more powerful.\nTypeScript supports many common patterns such as implementing interfaces, inheritance, and static methods.</p>\n<p>We’ll cover classes later in this guide.</p>\n<h2 id=\"rethinking-types\" style=\"position:relative;\"><a href=\"#rethinking-types\" aria-label=\"rethinking types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Rethinking Types</h2>\n<p>TypeScript’s understanding of a <em>type</em> is actually quite different from C# or Java’s.\nLet’s explore some differences.</p>\n<h3 id=\"nominal-reified-type-systems\" style=\"position:relative;\"><a href=\"#nominal-reified-type-systems\" aria-label=\"nominal reified type systems permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nominal Reified Type Systems</h3>\n<p>In C# or Java, any given value or object has one exact type - either <code>null</code>, a primitive, or a known class type.\nWe can call methods like <code>value.GetType()</code> or <code>value.getClass()</code> to query the exact type at runtime.\nThe definition of this type will reside in a class somewhere with some name, and we can’t use two classes with similar shapes in lieu of each other unless there’s an explicit inheritance relationship or commonly-implemented interface.</p>\n<p>These aspects describe a <em>reified, nominal</em> type system.\nThe types we wrote in the code are present at runtime, and the types are related via their declarations, not their structures.</p>\n<h3 id=\"types-as-sets\" style=\"position:relative;\"><a href=\"#types-as-sets\" aria-label=\"types as sets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Types as Sets</h3>\n<p>In C# or Java, it’s meaningful to think of a one-to-one correspondence between runtime types and their compile-time declarations.</p>\n<p>In TypeScript, it’s better to think of a type as a <em>set of values</em> that share something in common.\nBecause types are just sets, a particular value can belong to <em>many</em> sets at the same time.</p>\n<p>Once you start thinking of types as sets, certain operations become very natural.\nFor example, in C#, it’s awkward to pass around a value that is <em>either</em> a <code>string</code> or <code>int</code>, because there isn’t a single type that represents this sort of value.</p>\n<p>In TypeScript, this becomes very natural once you realize that every type is just a set.\nHow do you describe a value that either belongs in the <code>string</code> set or the <code>number</code> set?\nIt simply belongs to the <em>union</em> of those sets: <code>string | number</code>.</p>\n<p>TypeScript provides a number of mechanisms to work with types in a set-theoretic way, and you’ll find them more intuitive if you think of types as sets.</p>\n<h3 id=\"erased-structrual-types\" style=\"position:relative;\"><a href=\"#erased-structrual-types\" aria-label=\"erased structrual types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Erased Structrual Types</h3>\n<p>In TypeScript, objects are <em>not</em> of a single exact type.\nFor example, if we construct an object that satisfies an interface, we can use that object where that interface is expected even though there was no declarative relationship between the two.</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <span class='lsp'>Pointlike <span class='lsp-result'>interface Pointlike</span></span></span>\n<span style=\"color: #000000\">  <span class='lsp'>x:<span class='lsp-result'>(property) Pointlike.x: number</span></span> number;</span>\n<span style=\"color: #000000\">  <span class='lsp'>y:<span class='lsp-result'>(property) Pointlike.y: number</span></span> number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <span class='lsp'>Named <span class='lsp-result'>interface Named</span></span></span>\n<span style=\"color: #000000\">  <span class='lsp'>name:<span class='lsp-result'>(property) Named.name: string</span></span> string;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>printPoint(<span class='lsp-result'>function printPoint(point: Pointlike): void</span></span><span class='lsp'>point:<span class='lsp-result'>(parameter) point: Pointlike</span></span> <span class='lsp'>Pointlike)<span class='lsp-result'>interface Pointlike</span></span> {</span>\n<span style=\"color: #000000\">  <span class='lsp'>console.<span class='lsp-result'>var console: Console</span></span><span class='lsp'>log(<span class='lsp-result'>(method) Console.log(message?: any, ...optionalParams: any[]): void</span></span></span><span style=\"color: #A31515\">\"x = \"</span><span style=\"color: #000000\"> + <span class='lsp'>point.<span class='lsp-result'>(parameter) point: Pointlike</span></span><span class='lsp'>x <span class='lsp-result'>(property) Pointlike.x: number</span></span>+ </span><span style=\"color: #A31515\">\", y = \"</span><span style=\"color: #000000\"> + <span class='lsp'>point.<span class='lsp-result'>(parameter) point: Pointlike</span></span><span class='lsp'>y)<span class='lsp-result'>(property) Pointlike.y: number</span></span></span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>printName(<span class='lsp-result'>function printName(x: Named): void</span></span><span class='lsp'>x:<span class='lsp-result'>(parameter) x: Named</span></span> <span class='lsp'>Named)<span class='lsp-result'>interface Named</span></span> {</span>\n<span style=\"color: #000000\">  <span class='lsp'>console.<span class='lsp-result'>var console: Console</span></span><span class='lsp'>log(<span class='lsp-result'>(method) Console.log(message?: any, ...optionalParams: any[]): void</span></span></span><span style=\"color: #A31515\">\"Hello, \"</span><span style=\"color: #000000\"> + <span class='lsp'>x.<span class='lsp-result'>(parameter) x: Named</span></span><span class='lsp'>name)<span class='lsp-result'>(property) Named.name: string</span></span></span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> <span class='lsp'>obj <span class='lsp-result'>const obj: {&#13;    x: number;&#13;    y: number;&#13;    name: string;&#13;}</span></span>= {</span>\n<span style=\"color: #000000\">  <span class='lsp'>x:<span class='lsp-result'>(property) x: number</span></span></span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  <span class='lsp'>y:<span class='lsp-result'>(property) y: number</span></span></span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  <span class='lsp'>name:<span class='lsp-result'>(property) name: string</span></span></span><span style=\"color: #A31515\">\"Origin\"</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #000000\"><span class='lsp'>printPoint(<span class='lsp-result'>function printPoint(point: Pointlike): void</span></span><span class='lsp'>obj)<span class='lsp-result'>const obj: {&#13;    x: number;&#13;    y: number;&#13;    name: string;&#13;}</span></span></span>\n<span style=\"color: #000000\"><span class='lsp'>printName(<span class='lsp-result'>function printName(x: Named): void</span></span><span class='lsp'>obj)<span class='lsp-result'>const obj: {&#13;    x: number;&#13;    y: number;&#13;    name: string;&#13;}</span></span></span></code></div></pre>\n<p>TypeScript’s type system is <em>structural</em>, not nominal: We can use <code>obj</code> as a <code>Pointlike</code> because it has <code>x</code> and <code>y</code> properties that are both numbers.\nThe relationships between types are determined by the properties they contain, not whether they were declared with some particular relationship.</p>\n<p>TypeScript’s type system is also <em>not reified</em>: There’s nothing at runtime that will tell us that <code>obj</code> is <code>Pointlike</code>.\nIn fact, the <code>Pointlike</code> type is not present <em>in any form</em> at runtime.</p>\n<p>Going back to the idea of <em>types as sets</em>, we can think of <code>obj</code> as being a member of both the <code>Pointlike</code> set of values and the <code>Named</code> set of values.</p>\n<h3 id=\"consequences-of-structural-typing\" style=\"position:relative;\"><a href=\"#consequences-of-structural-typing\" aria-label=\"consequences of structural typing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consequences of Structural Typing</h3>\n<p>OOP programmers are often surprised by two particular aspects of structural typing.</p>\n<h4 id=\"empty-types\" style=\"position:relative;\"><a href=\"#empty-types\" aria-label=\"empty types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Empty Types</h4>\n<p>The first is that the <em>empty type</em> seems to defy expectation:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> <span class='lsp'>Empty <span class='lsp-result'>class Empty</span></span>{}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>fn(<span class='lsp-result'>function fn(arg: Empty): void</span></span><span class='lsp'>arg:<span class='lsp-result'>(parameter) arg: Empty</span></span> <span class='lsp'>Empty)<span class='lsp-result'>class Empty</span></span> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// do something?</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// No error, but this isn't an 'Empty' ?</span>\n<span style=\"color: #000000\"><span class='lsp'>fn(<span class='lsp-result'>function fn(arg: Empty): void</span></span>{ <span class='lsp'>k:<span class='lsp-result'>(property) k: number</span></span></span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\"> });</span></code></div></pre>\n<p>TypeScript determines if the call to <code>fn</code> here is valid by seeing if the provided argument is a valid <code>Empty</code>.\nIt does so by examining the <em>structure</em> of <code>{ k: 10 }</code> and <code>class Empty { }</code>.\nWe can see that <code>{ k: 10 }</code> has <em>all</em> of the properties that <code>Empty</code> does, because <code>Empty</code> has no properties.\nTherefore, this is a valid call!</p>\n<p>This may seem surprising, but it’s ultimately a very similar to relationship to one enforced in nominal OOP languages.\nA subclass cannot <em>remove</em> a property of its base class, because doing so would destroy the natural subtype relationship between the derived class and its base.\nStructural type systems simply identify this relationship implicitly by describing subtypes in terms of having properties of compatible types.</p>\n<h4 id=\"identical-types\" style=\"position:relative;\"><a href=\"#identical-types\" aria-label=\"identical types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Identical Types</h4>\n<p>Another frequent source of surprise comes with identical types:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Car {</span>\n<span style=\"color: #000000\">  drive() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// hit the gas</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Golfer {</span>\n<span style=\"color: #000000\">  drive() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// hit the ball far</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// No error?</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> w: Car = </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> Golfer();</span></code></div></pre>\n<p>Again, this isn’t an error because the <em>structures</em> of these classes are the same.\nWhile this may seem like a potential source of confusion, in practice, identical classes that shouldn’t be related are not common.</p>\n<p>We’ll learn more about how classes relate to each other in the Classes chapter.</p>\n<h3 id=\"reflection\" style=\"position:relative;\"><a href=\"#reflection\" aria-label=\"reflection permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reflection</h3>\n<p>OOP programmers are accustomed to being able to query the type of any value, even a generic one:</p>\n<pre class=\"shiki\"><div class=\"language-id\">csharp</div><div class='code-container'><code><span style=\"color: #008000\">// C#</span>\n<span style=\"color: #0000FF\">static</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">void</span><span style=\"color: #000000\"> PrintType&lt;T&gt;() {</span>\n<span style=\"color: #000000\">    Console.WriteLine(</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\">(</span><span style=\"color: #0000FF\">T</span><span style=\"color: #000000\">).Name);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Because TypeScript’s type system is fully erased, information about e.g. the instantiation of a generic type parameter is not available at runtime.</p>\n<p>JavaScript does have some limited primitives like <code>typeof</code> and <code>instanceof</code>, but remember that these operators are still working on the values as they exist in the type-erased output code.\nFor example, <code>typeof (new Car())</code> will be <code>\"object\"</code>, not <code>Car</code> or <code>\"Car\"</code>.</p>\n<hr>\n<p>This is an overview, from here you should read <a href=\"/docs/handbook/basic-types.html\">through the handbook</a> or explore the <a href=\"/play#show-examples\">Playground examples</a></p>","headings":[{"value":"Co-learning JavaScript","depth":2},{"value":"Rethinking the Class","depth":2},{"value":"Free Functions and Data","depth":3},{"value":"Static Classes","depth":3},{"value":"OOP in TypeScript","depth":2},{"value":"Rethinking Types","depth":2},{"value":"Nominal Reified Type Systems","depth":3},{"value":"Types as Sets","depth":3},{"value":"Erased Structrual Types","depth":3},{"value":"Consequences of Structural Typing","depth":3},{"value":"Empty Types","depth":4},{"value":"Identical Types","depth":4},{"value":"Reflection","depth":3}],"frontmatter":{"permalink":"/docs/handbook/typescript-in-5-minutes-oop.html","title":"TypeScript for Java/C# Programmers"}}},"pageContext":{"slug":"/docs/handbook/typescript-in-5-minutes-oop.html","isOldHandbook":true}}}