<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TypeScript Archives - Ronnie Schaniel</title>
	<atom:link href="https://ronnieschaniel.com/category/typescript/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Blog</description>
	<lastBuildDate>Wed, 10 Nov 2021 07:24:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Rule Apparatus &#8211; Simple TypeScript Rule Engine</title>
		<link>https://ronnieschaniel.com/typescript/rule-apparatus-simple-typescript-rule-engine/</link>
		
		<dc:creator><![CDATA[ronnieschaniel@hey.com]]></dc:creator>
		<pubDate>Wed, 10 Nov 2021 07:20:58 +0000</pubDate>
				<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://ronnieschaniel.com/?p=893</guid>

					<description><![CDATA[<p>A minimalist rule engine available as npm package.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/rule-apparatus-simple-typescript-rule-engine/">Rule Apparatus &#8211; Simple TypeScript Rule Engine</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Sometimes we&#8217;ve got business rules that we want to model as a table of rule in our code. I created a minimalist implementation for such a rule engine in TypeScript.</p>



<h2 class="wp-block-heading">Creating Rules</h2>



<p>For our demo we want to create rules regarding salary ranges for software engineers. Our salaries are dependent on the following 4 characteristics: university degree, minimum years of experience, engineer has a blog, and last year&#8217;s performance. Our generic rule looks like the following:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">interface Rule {
    input: Input;
    output: Output;
}</code></pre>



<p>Hence, we can define the Input as an object considering all the input variables:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">interface Input {
    universityDegree: 'NONE' | 'BACHELOR' | 'MASTER';
    minimumYearsOfExperience: 0 | 2 | 5 | 8 | 10 | 15;
    hasBlog: boolean;
    lastYearsPerformance: 1 | 2 | 3 | 4 | 5;
}</code></pre>



<p>Because the output should have a lower and upper salary boundary we define an Output interface with two number fields:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">interface Output {
    minSalary: number;
    maxSalary: number;
}</code></pre>



<p>Based on these two types we can now define the rules:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">const ruleDefinitions: Rule[] = [
    {
        input: { universityDegree: 'MASTER', minimumYearsOfExperience: 8, hasBlog: false, lastYearsPerformance: 3 },
        output: { minSalary: 120_000, maxSalary: 130_000 }
    },
    {
        input: { universityDegree: 'NONE', minimumYearsOfExperience: 10, hasBlog: true, lastYearsPerformance: 4 },
        output: { minSalary: 125_000, maxSalary: 135_000 }
    }
];</code></pre>



<p>We see that you don&#8217;t really need a university degree to get a good salary. If you work well and write a tech blog you can even get a higher salary than people having a master&#8217;s degree <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</p>



<h2 class="wp-block-heading">Evaluating Rules</h2>



<p>The rule evaluation is simple. We just use the evaluate() method of rule-apparatus, define the input and output types, and call the method by passing the rules alongside the input arguments (here candidates):</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">let candidateA: Input = { universityDegree: 'MASTER', minimumYearsOfExperience: 8, hasBlog: false, lastYearsPerformance: 3 };
let candidateB: Input = { universityDegree: 'NONE', minimumYearsOfExperience: 10, hasBlog: true, lastYearsPerformance: 4 };

expect(evaluate&lt;Input, Output>(ruleDefinitions, candidateA)).toEqual({
    minSalary: 120_000,
    maxSalary: 130_000,
});
expect(evaluate&lt;Input, Output>(ruleDefinitions, candidateB)).toEqual({
    minSalary: 125_000,
    maxSalary: 135_000,
});</code></pre>



<p>We get the expected salary ranges for our two candidates back from the evaluate method. And everything is type safe.</p>



<h2 class="wp-block-heading">Rule apparatus sources and installation</h2>



<p>These rules defined above could also be defined in a JSON format and delivered to wherever the evaluation should happen. The functionality is kept basic intentionally. There is for example no greaterThan functionality at the moment. It&#8217;s the responsibility of the consumer to define the inputs intelligently.</p>



<p>Please check <a href="https://github.com/rschaniel/rule-apparatus" target="_blank" rel="noreferrer noopener">GitHub</a> to see the full code for this simple TypeScript rule engine. If you see any issues or potential for improvements please file an <a href="https://github.com/rschaniel/rule-apparatus/issues" target="_blank" rel="noreferrer noopener">issue</a>. The package itself can be found here on <a href="https://www.npmjs.com/package/rule-apparatus" target="_blank" rel="noreferrer noopener">npmjs</a> or can be installed by executing:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">npm i rule-apparatus</code></pre>
<p>The post <a href="https://ronnieschaniel.com/typescript/rule-apparatus-simple-typescript-rule-engine/">Rule Apparatus &#8211; Simple TypeScript Rule Engine</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>TypeScript Coding Challenge #5 &#8211; Type for Event Handlers like onClick</title>
		<link>https://ronnieschaniel.com/typescript/type-for-event-handlers-like-onclick/</link>
		
		<dc:creator><![CDATA[ronnieschaniel@hey.com]]></dc:creator>
		<pubDate>Mon, 13 Sep 2021 18:12:50 +0000</pubDate>
				<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://ronnieschaniel.com/?p=799</guid>

					<description><![CDATA[<p>How to best type 'onChange', 'onClick', etc.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/type-for-event-handlers-like-onclick/">TypeScript Coding Challenge #5 &#8211; Type for Event Handlers like onClick</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Let&#8217;s assume we have the HTML events like click, enter, etc. And we want to have a type for strings like &#8216;onClick&#8217;, &#8216;onEnter&#8217;, etc. A first approach could look like this:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">type EventHandlerNameUnion = 'onChange' | 'onClick'; // and so on</code></pre>



<p>While this works, it is not the best approach due to the following reasons:</p>



<ul class="wp-block-list"><li>It&#8217;s cumbersome to type all the union values</li><li>As soon as a new HTML event type is added we have to manually extend our type</li></ul>



<p>Generally, we want to have <a href="https://fettblog.eu/low-maintenance-types-typescript/" target="_blank" rel="noreferrer noopener">low maintenance types</a> in TypeScript. So, there has to be a better solution.</p>



<h2 class="wp-block-heading">Template Literal Types to the rescue</h2>



<p>Since we want to have a string in the end we can use template literal types to &#8220;generate&#8221; all the types:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">/*
Extract from <meta charset="utf-8">GlobalEventHandlersEventMap:

interface GlobalEventHandlersEventMap {
    ...
    "change": Event;
    "click": MouseEvent;
    ...
}
 */
type eventTypes = keyof GlobalEventHandlersEventMap;

type EventHandlerName = `on${Capitalize&lt;eventTypes>}`;</code></pre>



<p>If we hover on the type EventHandlerName we see:</p>



<figure class="wp-block-image size-large is-resized"><img fetchpriority="high" decoding="async" src="https://ronnieschaniel.com/wp-content/uploads/2021/09/template_literal_type_for_event_type_handler_string-1024x141.png" alt="" class="wp-image-800" width="768" height="106" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/09/template_literal_type_for_event_type_handler_string-1024x141.png 1024w, https://ronnieschaniel.com/wp-content/uploads/2021/09/template_literal_type_for_event_type_handler_string-300x41.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/09/template_literal_type_for_event_type_handler_string-768x106.png 768w, https://ronnieschaniel.com/wp-content/uploads/2021/09/template_literal_type_for_event_type_handler_string-1536x211.png 1536w, https://ronnieschaniel.com/wp-content/uploads/2021/09/template_literal_type_for_event_type_handler_string.png 1586w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>We are receiving &#8220;on&#8221; followed by a capitalised event name, e.g. &#8220;Abort&#8221;. Finally we are able to detect misspellings and other issue:</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" src="https://ronnieschaniel.com/wp-content/uploads/2021/09/event_type_name_compilation.png" alt="" class="wp-image-804" width="569" height="98" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/09/event_type_name_compilation.png 758w, https://ronnieschaniel.com/wp-content/uploads/2021/09/event_type_name_compilation-300x51.png 300w" sizes="(max-width: 569px) 100vw, 569px" /></figure>



<p> <br></p>
<p>The post <a href="https://ronnieschaniel.com/typescript/type-for-event-handlers-like-onclick/">TypeScript Coding Challenge #5 &#8211; Type for Event Handlers like onClick</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>TypeScript Coding Challenge #4 &#8211; Type for Required Fields</title>
		<link>https://ronnieschaniel.com/typescript/typescript-coding-challenge-4-type-for-required-fields/</link>
		
		<dc:creator><![CDATA[ronnieschaniel@hey.com]]></dc:creator>
		<pubDate>Mon, 03 May 2021 19:29:12 +0000</pubDate>
				<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://ronnieschaniel.com/?p=454</guid>

					<description><![CDATA[<p>We implement a generic type that reduces a type to only the required fields.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/typescript-coding-challenge-4-type-for-required-fields/">TypeScript Coding Challenge #4 &#8211; Type for Required Fields</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>This time we want to implement a type in TypeScript that returns us a type with all required fields of an object:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">type I = GetRequired&lt;{ foo: number, bar?: string }&gt; 
// expected to be { foo: number }</code></pre>



<h2 class="wp-block-heading">Intersection with undefined</h2>



<p>Let&#8217;s build this step by step. What types are actually behind <em>foo</em> and <em>bar</em>? It looks as follows:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">number // foo is obviously of type number
string | undefined // for bar we can either use string or undefined</code></pre>



<p>An optional field basically means that the possible types are the defined type (<em>string</em>) or <em>undefined</em>. So, we need some way to detect something that can be <em>undefined</em>. We would like to do this with an <a href="https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#intersection-types" target="_blank" rel="noreferrer noopener">intersection</a>. Then we could later on check with extends. Think about the following two types:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>testFoo = <strong>number </strong>&amp; <strong>undefined</strong>;
<strong>type </strong>testBar = (<strong>string </strong>| <strong>undefined</strong>) &amp; <strong>undefined</strong></code></pre>



<p>An intersection of number &amp; undefined can never happen, the type sets have no common elements. It&#8217;s different for the second case though. If we intersect <em>(string | undefined)</em> with <em>undefined</em>, the common type set is the one that contains just <em>undefined</em>. Our IDE helps us here as well:</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection.png" alt="" class="wp-image-458" width="381" height="78" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection.png 540w, https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection-300x61.png 300w" sizes="(max-width: 381px) 100vw, 381px" /></figure>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_with_undefined.png" alt="" class="wp-image-459" width="586" height="103" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_with_undefined.png 740w, https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_with_undefined-300x53.png 300w" sizes="(max-width: 586px) 100vw, 586px" /></figure>



<p>What have we learnt so far? An optional field can be of a certain type or <em>undefined</em>. And intersection of something containing <em>undefined</em> with <em>undefined</em> itself results in <em>undefined</em>.</p>



<h2 class="wp-block-heading">Looping through keys and checking intersection</h2>



<p>Now let&#8217;s build the whole thing starting with the simple &#8220;key/value&#8221; type defined like:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>KeysAndValues&lt;T&gt; = {
    [K <strong>in keyof </strong>T]: T[K]
}
// So, nothing else than { foo: number, bar?: string }</code></pre>



<p>Now let&#8217;s filter out <em>bar?</em> with the help of the intersection with <em>undefined</em>:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>II&lt;T&gt; = {
    [K <strong>in keyof </strong>T]: T[K] &amp; <strong>undefined extends never </strong>? K : <strong>never</strong>;
}</code></pre>



<p>If the intersection with <em>undefined</em> extends <em>never</em>, we return the key K. In the other cases we return <em>never</em>. This leaves us with the following:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>IIa = II&lt;{ foo: <strong>number</strong>, bar?: <strong>string </strong>}&gt;;

// equal to { foo: "foo"; bar?: undefined; }</code></pre>



<p>The left hand side of <em>II&lt;T></em> gives us just all the keys with <em>[K <strong>in keyof </strong>T]</em>. On the right hand side:</p>



<ul class="wp-block-list"><li>the intersection for <em>foo</em> extends <em>never</em> and therefore we return <em>K</em> which is in this case the key &#8220;foo&#8221;</li><li>for <em>bar</em> the intersection with <em>undefined</em> doesn&#8217;t extend never. So, we return <em>never</em> which leaves us with <em>undefined</em> in <em>IIa</em></li></ul>



<h2 class="wp-block-heading">Putting everything together</h2>



<p>At this moment we can determine the keys for required fields:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>RequiredKey&lt;T&gt; = {
    [K <strong>in keyof </strong>T]: T[K] &amp; <strong>undefined extends never </strong>? K : <strong>never</strong>;
}[<strong>keyof </strong>T];

<strong>type </strong>requiredKeysForI = RequiredKey&lt;{ foo: <strong>number</strong>, bar?: <strong>string </strong>}&gt;;
// "foo" | undefined</code></pre>



<p>The expression <em>{ foo: &#8220;foo&#8221;; bar?: undefined; }</em> accessed via keys <em>[keyof T]</em> gives <em>&#8220;foo&#8221; | undefined</em>.</p>



<p>Finally, we can use the required keys to construct the type:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>GetRequired&lt;T&gt; = {
    [K <strong>in </strong>RequiredKey&lt;T&gt;]: T[K];
};</code></pre>



<p>If we only loop through the required keys, we only get <em>foo</em>. So, this finally leaves us with:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>type </strong>I = GetRequired&lt;{ foo: <strong>number</strong>, bar?: <strong>string </strong>}&gt;</code></pre>



<p>Our IDE shows us that we have found a good type to reduce something to the required fields in TypeScript:</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_results.png" alt="" class="wp-image-460" width="550" height="125" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_results.png 806w, https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_results-300x68.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/05/typescript_required_fields_intersection_results-768x173.png 768w" sizes="(max-width: 550px) 100vw, 550px" /></figure>



<p>If you&#8217;re interested in a type for chainable options, check out this <a href="https://ronnieschaniel.com/typescript/type-chainable-options/">post</a>.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/typescript-coding-challenge-4-type-for-required-fields/">TypeScript Coding Challenge #4 &#8211; Type for Required Fields</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>TypeScript Coding Challenge #3 &#8211; Type Chainable Options</title>
		<link>https://ronnieschaniel.com/typescript/type-chainable-options/</link>
		
		<dc:creator><![CDATA[ronnieschaniel@hey.com]]></dc:creator>
		<pubDate>Thu, 01 Apr 2021 13:46:56 +0000</pubDate>
				<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://ronnieschaniel.com/?p=397</guid>

					<description><![CDATA[<p>Today we want to create types for an object with chainable method calls. </p>
<p>The post <a href="https://ronnieschaniel.com/typescript/type-chainable-options/">TypeScript Coding Challenge #3 &#8211; Type Chainable Options</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In <a href="https://ronnieschaniel.com/typescript-coding-challenge/all-unique-characters/">all unique characters</a> and <a href="https://ronnieschaniel.com/typescript-coding-challenge/typescript-coding-challenge-2-string-compression/">string compression</a> we started with 2 easy coding challenges. But they were not really TypeScript specific. They could have been programmed in JavaScript too and it wouldn&#8217;t have made much difference. So, what challenges are really TypeScript specific? Those that involve types!</p>



<p>Today we want to create types for an object with chainable method calls. Specifically, we need to provide types for two functions:</p>



<p><em>option(key, value)</em> <br><em>get()</em></p>



<p>For <em>key</em> of <em>option</em> we can only pass strings while the <em>value</em> can be anything. In the end we need to provide a type or interface for <em>Chainable</em> as used below:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>declare const </strong>config: Chainable;

<strong>const </strong>result: Result  = config
    .option('foo', 123)
    .option('name', 'type-challenges')
    .option('bar', { value: 'Hello World' })
    .get();


<strong>interface </strong>Result {
    foo: <strong>number</strong>,
    name: <strong>string</strong>,
    bar: {
        value: <strong>string
    </strong>}
}</code></pre>



<p>Credits to antfu (<a href="https://github.com/type-challenges/type-challenges" target="_blank" rel="noreferrer noopener">https://github.com/type-challenges/type-challenges</a>) for this and more great examples.</p>



<h2 class="wp-block-heading">Simple solution</h2>



<p>Let&#8217;s start by creating a simple interface <em>Chainable</em> with two properties that are functions. For <em>option</em> the <em>key</em> parameter is of type <em>string</em> while <em>value</em> can be <em>any</em>. The result of the <em>option</em> function is again of type <em>Chainable</em>. For the second method <em>get </em>we just define the return type <em>Result</em> defined above.</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>interface </strong>Chainable {
    option: (key: <strong>string</strong>, value: <strong>any</strong>) =&gt; Chainable,
    get: () =&gt; Result
}</code></pre>



<p>When checking our IDE everything looks fine. No red squiggly lines:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="972" height="510" src="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_simple_variant.png" alt="The variable result does conform to the type Result." class="wp-image-401" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_simple_variant.png 972w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_simple_variant-300x157.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_simple_variant-768x403.png 768w" sizes="(max-width: 972px) 100vw, 972px" /></figure>



<p>The <em>result</em> conforms to the type <em>Result</em> and the methods on the <em>Chainable </em>config are typed. But we can do better than that. </p>



<h2 class="wp-block-heading">Solution without explicit return type</h2>



<p>The goal is always to have code that requires low maintenance and easy extension. Types are no different in that regard. We can actually enhance the types for our <em>Chainable</em> interface and get rid of <em>Result</em>. But first let&#8217;s see what happens if we remove the <em>Result</em> type from <em>result</em>.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="378" src="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_any-1024x378.png" alt="The type of result is any object {}" class="wp-image-404" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_any-1024x378.png 1024w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_any-300x111.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_any-768x284.png 768w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_any.png 1116w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The method <em>get</em> is returning {} as type and therefore also our result is of type object. Not very safe. As a consequence we also can&#8217;t access its properties:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="355" src="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_property-1024x355.png" alt="Property access on result.foo not working" class="wp-image-403" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_property-1024x355.png 1024w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_property-300x104.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_property-768x266.png 768w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_property.png 1258w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now let&#8217;s introduce some generics to type <em>Chainable</em> and our <em>result</em>:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>interface </strong>Chainable&lt;P = {}&gt; {
    option&lt;K <strong>extends string</strong>, V&gt;(key: K, value: V): Chainable&lt;P &amp; { [key <strong>in </strong>K]: V }&gt;,
    get: () =&gt; P
}

<strong>declare const </strong><em>config</em>: Chainable;

<strong>const </strong><em>result </em>= <em>config
    </em>.option('foo', 123)
    .option('name', 'type-challenges')
    .option('bar', { value: 'Hello World' })
    .get();</code></pre>



<p>The <em>Chainable</em> interface gets a generic type parameter <em>P</em> with a default value. This <em>P</em> also &#8220;connects&#8221; the two methods. The <em>key</em> parameter in <em>option</em> is following the generic type parameter <em>K</em> which is constrained to <em>string</em>. This makes sense because this key will end up as object key for the output where we want to have <em>string</em> as type. <br>On the return side of option we make use of <a href="https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#intersection-types" target="_blank" rel="noreferrer noopener">Intersection Types</a>, generics and recursion. <em>P</em> gets &#8220;extended&#8221; with a property having key of type <em>K</em> and a type <em>V</em>. <br>The intersection is important to type chainable method calls in TypeScript and not lose the type from previous method calls. I first ended up with a type that only had <em>bar </em>as property.<br>Finally the method <em>get</em> is returning something of type <em>P</em>.</p>



<p>After that change our IDE is happy too and <em>result</em> is properly typed:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="462" src="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_type-1024x462.png" alt="Variant with generics that has the key names from the option method as properties." class="wp-image-406" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_type-1024x462.png 1024w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_type-300x135.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_type-768x347.png 768w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_type.png 1320w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>We not only see the properties on <em>result</em> (<em>bar, foo, name</em>) but also the type of the property (<em>{value: string}, number, string</em>). Hovering over <em>result</em> shows the complete type:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="411" src="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_complete_type-1024x411.png" alt="Complete result type displayed in the IDE with the intersections." class="wp-image-407" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_complete_type-1024x411.png 1024w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_complete_type-300x120.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_complete_type-768x308.png 768w, https://ronnieschaniel.com/wp-content/uploads/2021/04/ts_coding_challenge_3_type_chainable_implicit_result_complete_type.png 1236w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>This is it for now. You&#8217;ve learnt to type chainable methods in TypeScript. Please find the sources on <a href="https://github.com/rschaniel/typescript_coding_challenges/tree/main/src/type_chainable_options" target="_blank" rel="noreferrer noopener">GitHub</a>. If you have any questions or ideas for further TypeScript challenges, you can reach out to me on Twitter <a href="https://twitter.com/ronnieschaniel" target="_blank" rel="noreferrer noopener">@ronnieschaniel</a>.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/type-chainable-options/">TypeScript Coding Challenge #3 &#8211; Type Chainable Options</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>TypeScript Coding Challenge #2 &#8211; String Compression</title>
		<link>https://ronnieschaniel.com/typescript/typescript-coding-challenge-2-string-compression/</link>
		
		<dc:creator><![CDATA[ronnieschaniel@hey.com]]></dc:creator>
		<pubDate>Mon, 29 Mar 2021 18:30:28 +0000</pubDate>
				<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://ronnieschaniel.com/?p=373</guid>

					<description><![CDATA[<p>Our task is to write a function that does String compression in TypeScript.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/typescript-coding-challenge-2-string-compression/">TypeScript Coding Challenge #2 &#8211; String Compression</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Our task today is to write a function for String compression in TypeScript. </p>



<p><em>Implement a method that replaces repeated characters by the character and a number indicating how often the character occurs in a single repetition. To give you one example: aabcccccaaa should be compressed to a2b1c5a3. If the compressed string would not become smaller than the original one, we should return the original string. A string has only uppercase and lowercase letters (a-z).</em></p>



<h2 class="wp-block-heading">Setup</h2>



<p>We&#8217;re again using a custom &#8220;test function&#8221; as in our previous post about <a href="https://ronnieschaniel.com/typescript-coding-challenge/all-unique-characters/">all unique characters</a>. This time we just rename it to &#8220;assert&#8221;, change the order of the parameters and add some generics to ensure we&#8217;re working with the correct types:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>function </strong>assert&lt;I, O&gt;(input: I, fn: (value: I) =&gt; O, expectedValue: O) {
    <strong>const </strong>result = fn(input);
    <strong>const </strong>assertionString = result === expectedValue ? '\u2713' : `\u2717 expected ${expectedValue}`;
    <strong>const </strong>color = result === expectedValue ? '\x1b[32m' : '\x1b[31m';
    console.log(color, `'${input}' =&gt; ${result} ${assertionString}`, '\x1b[0m');
}</code></pre>



<p>The &#8216;\u2713&#8217;, etc. will ensure our output is either appearing in green or red depending on the success or failure of comparing the actual output (<em>result</em>) with the <em>expectedValue</em>. Check out this <a href="https://blog.bitsrc.io/coloring-your-terminal-using-nodejs-eb647d4af2a2" target="_blank" rel="noreferrer noopener">post</a> to learn about colouring your Node JS terminal output. </p>



<h2 class="wp-block-heading">Solution</h2>



<p>We define a function that accepts a string input. First, we take care of an edge case and return the input if the string length is smaller than 3. For example the input aa with length 2 would be compressed to a2 which is unnecessary.<br>Now let&#8217;s take care of the remaining cases. In a for loop consecutive characters are compared and the <em>repetitionCount</em> is increased if the characters following each other are the same. As soon as the characters stop repeating themselves we can add the character alongside the <em>repetitionCount</em> to the <em>output</em>. At the same time we should reset the <em>repetitionCount</em> to the initial value of 0.<br>Finally we check whether the compression did really help and only return the compressed variant if it&#8217;s shorter.</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>function </strong>compressString(input: <strong>string</strong>): <strong>string </strong>{
    <strong>if </strong>(input.length &lt; 3) {
        <strong>return </strong>input;
    }

    <strong>let </strong>output = '';
    <strong>let </strong>repetitionCount = 0;
    <strong>for </strong>(<strong>let </strong>i = 0; i &lt; input.length; i++) {
        repetitionCount++;
        <strong>if </strong>(input[i] !== input[i+1]) {
            output += `${input[i]}${repetitionCount}`;
            repetitionCount = 0;
        }
    }
    <strong>return </strong>output.length &lt; input.length ? output : input;
}</code></pre>



<p>Let&#8217;s run this with a few examples:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">assert('test', compressString, 'test');
assert('aabcccccaaa', compressString, 'a2b1c5a3');
assert('ttuuuz', compressString, 'ttuuuz');
assert('eeeee', compressString, 'e5');
assert('a', compressString, 'a');
assert('aa', compressString, 'aa');
assert('aaa', compressString, 'a3');
assert('', compressString, '');</code></pre>



<p>This shows us the following in our console:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="896" height="308" src="https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_2_string_compression.png" alt="The string comparison test output in the console showing that everything worked fine." class="wp-image-389" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_2_string_compression.png 896w, https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_2_string_compression-300x103.png 300w, https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_2_string_compression-768x264.png 768w" sizes="(max-width: 896px) 100vw, 896px" /></figure>



<p>The first string &#8216;test&#8217; is not worth compressing as it would end up being &#8216;t1e1s1t1&#8217; which is not shorter than &#8216;test&#8217; itself. We can get rid of a bit of string length for the second example though: &#8216;aabcccccaaa&#8217; ends up as &#8216;a2b1c5a3&#8217;. </p>
<p>The post <a href="https://ronnieschaniel.com/typescript/typescript-coding-challenge-2-string-compression/">TypeScript Coding Challenge #2 &#8211; String Compression</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>TypeScript Coding Challenge #1 &#8211; All Unique Characters</title>
		<link>https://ronnieschaniel.com/typescript/all-unique-characters/</link>
		
		<dc:creator><![CDATA[ronnieschaniel@hey.com]]></dc:creator>
		<pubDate>Fri, 19 Mar 2021 15:01:00 +0000</pubDate>
				<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://ronnieschaniel.com/?p=309</guid>

					<description><![CDATA[<p>Implement an algorithm to check if a string has all unique characters (without data structures).</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/all-unique-characters/">TypeScript Coding Challenge #1 &#8211; All Unique Characters</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this post we want to implement a TypeScript algorithm that tells us if a string contains all unique characters:</p>



<p><em>Implement an algorithm to determine if a string has all unique characters. What if you cannot use additional data structures?</em></p>



<p>We&#8217;re going to split this into two parts. First, we start with the simple variant where we are able to use additional data structures and in the second part we can make it more difficult. </p>



<p>But first let&#8217;s quickly setup some code to help us test our solutions later.</p>



<h2 class="wp-block-heading">Setup</h2>



<p>As a first step we define the interface for the function that implements our solution:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">fn: (value: <strong>string</strong>) =&gt; <strong>boolean</strong></code></pre>



<p>Hence, we are setting up the following <em>testFunction</em> to pass the input string, alongside the expected value and the function that implements our solution.</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>function </strong>testFunction(input: <strong>string</strong>, expectedValue: <strong>boolean</strong>, fn: (value: <strong>string</strong>) =&gt; <strong>boolean</strong>) {
    <strong>const </strong>result = fn(input);
    <strong>const </strong>assertionString = result === expectedValue ? '\u2713' : `\u2717 expected ${expectedValue}`;
    <strong>const </strong>color = result === expectedValue ? '\x1b[32m' : '\x1b[31m';
    console.log(color, `'${input}' =&gt; ${result} ${assertionString}`);
}</code></pre>



<h2 class="wp-block-heading">Solution with additional data structures</h2>



<p>We know that in JavaScript the&nbsp;<strong><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set" target="_blank" rel="noreferrer noopener">Set</a></code></strong>&nbsp;object lets you store unique values of any type, whether primitive values&nbsp;or object references. We can use this characteristic to solve our problem:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>function </strong>hasAllUniqueCharacters(input: <strong>string</strong>): <strong>boolean </strong>{
    <strong>const </strong>characterSet = <strong>new </strong>Set(input.split(''));
    <strong>return </strong>input.length === characterSet.size;
}</code></pre>



<p>We test this solution by calling our <em>testFunction</em> defined above:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">console.log('-----------------------------------');
testFunction('test', <strong>false</strong>, hasAllUniqueCharacters);
testFunction('abc', <strong>true</strong>, hasAllUniqueCharacters);
testFunction('all', <strong>false</strong>, hasAllUniqueCharacters);
testFunction('', <strong>true</strong>, hasAllUniqueCharacters);</code></pre>



<p>And in our console we can see as a result:</p>



<figure class="wp-block-image size-large mt-6"><img decoding="async" width="766" height="146" src="https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_1_solution_1_results.png" alt="Test results for the first function. Showing that the function returns false for 'test' and 'all'. Whereas true is returned for 'abc' and empty string." class="wp-image-325" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_1_solution_1_results.png 766w, https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_1_solution_1_results-300x57.png 300w" sizes="(max-width: 766px) 100vw, 766px" /></figure>



<p>Everything is fine. Let&#8217;s move on to the second part of the task and tackle the variant without using any additional data structures.</p>



<h2 class="wp-block-heading">Solution without additional data structures</h2>



<p>For this solution we have to loop through the characters and compare them with each other. If we then find two identical characters and their indices are not equal (i.e. not the same character in the input) we can return false.</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript"><strong>function </strong>hasAllUniqueCharactersV2(input: <strong>string</strong>): <strong>boolean </strong>{
    <strong>for </strong>(<strong>let </strong>i = 0; i &lt; input.length; i++) {
        <strong>for </strong>(<strong>let </strong>j = 0; j &lt; input.length; j++) {
            <strong>if </strong>(input[i] === input[j] &amp;&amp; i !== j) {
                <strong>return false</strong>;
            }
        }
    }

    <strong>return true</strong>;
}</code></pre>



<p>This algorithm has a time complexity of O(n<sup>2</sup>). One alternative would be to sort the input string&#8217;s characters and compare neighbouring characters. This would bring down the time complexity to O(n log n).</p>



<p>Anyway, testing this second function (hasAllUniqueCharactersV2) works analog to the previous one. We just pass the function as third parameter:</p>



<pre class="wp-block-code"><code lang="typescript" class="language-typescript">testFunction('test', <strong>false</strong>, hasAllUniqueCharactersV2);
// etc.</code></pre>



<p>This gives us the following output in the console:</p>



<figure class="wp-block-image size-large mt-6"><img decoding="async" width="754" height="196" src="https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_1_solution_2_results.png" alt="Test results for the second function. Again showing that the function returns false for 'test' and 'all'. Whereas true is returned for 'abc' and empty string." class="wp-image-324" srcset="https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_1_solution_2_results.png 754w, https://ronnieschaniel.com/wp-content/uploads/2021/03/ts_coding_challenge_1_solution_2_results-300x78.png 300w" sizes="(max-width: 754px) 100vw, 754px" /></figure>



<p>Problem solved! We have shown two possible implementations in TypeScript to determine if a string contains all unique characters.</p>



<p>Note: Why didn&#8217;t I use a test framework? Because for now I prefer the 4 lines of <em>testFunction</em>. No need to install and setup some 3rd party code.</p>
<p>The post <a href="https://ronnieschaniel.com/typescript/all-unique-characters/">TypeScript Coding Challenge #1 &#8211; All Unique Characters</a> appeared first on <a href="https://ronnieschaniel.com">Ronnie Schaniel</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
