TypescriptGrammarly.md


Typescriptに特徴的な部分のみ


## 連想配列

インデックスシグニチャでの型宣言
(シグネチャ=引数や返り値の組み合わせ)

```ts
let obj: { [key: string]: string; } = {
    "hoge": "ほげ",
    "huga": "ふが",
}
obj.piyo = "ぴよ";
```

型推論により、`hoge`と`huga`以外のプロパティを受け入れなくなっている

```ts
let obj = {
    "hoge": "ほげ",
    "huga": "ふが",
}
obj.piyo = "ぴよ"; // エラー
```



## 共用型

複数の型を宣言する。どれかに該当すれば良い

```ts
let hoge: string | boolean;
hoge = "hoge";
hoge = true;
hoge = 1; // エラー
```



## 省略可な引数

引数の最後に`?`をつける。オプション。

```ts
function say(serif?: string) {
    console.log(serif);
}
say();
```



## オーバーロード

```ts
// 最初に型チェックのためにシグニチャだけで関数を宣言する
function show(a: number): number;
function show(a: string, b: boolean): string;

// 上記に宣言したシグニチャの全てに対応する関数を実装する
function show(a: any, b: any): any {
  if (typeof a === "string") {
    return b ? "[true]" + a : "[false]" + a;
  }
  if(typeof a === "number"){
    return a;
  }
}

console.log(show("hoge", true)); // [true]hoge
console.log(show("h

tips

# Tips

##### To add a specific program to your PATH
```
PATH=$PATH:~/opt/bin
or
PATH=~/opt/bin:$PATH
   ``` 


#### To run localhost from Linode or digital ocean
`yarn install && HOST=(hostname) yarn start`

`node index.js && HOST=(hostname)`

For rails 
`rails s -b 0.0.0.0`

#### To set up git completion on bashrc

```
curl -sL http://bit.ly/2JagFeN > ~/.git-completion.bash
```

Then for mac run:
```
echo 'source $HOME/.git-completion.bash' >> ~/.bash_profile
```
Or ubuntu run:
```
echo 'source $HOME/.git-completion.bash' >> ~/.bashrc
```

#### To display git branch add to your bashrc or bash_profile
```
git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}

export PS1="\u@\h\[\033[01;32m\][\W]\[\033[01;34m\]\$(git_branch)\[\033[00m\]\$ "

```
That snippet needs to replace:
```
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($de

Multiple Unique Numbers Based on Some Length

var getRandomNumbers = function(howMany, upperLimit) {
      var limit = howMany,
        amount = 3,
        lower_bound = 1,
        upper_bound = upperLimit,
        unique_random_numbers = [];

      if (amount > limit) limit = amount; //Infinite loop if you want more unique
      //Natural numbers than exist in a
      // given range
      while (unique_random_numbers.length < limit) {
        var random_number = Math.floor(
          Math.random() * (upper_bound - lower_bound) + lower_bound
        );
        if (unique_random_numbers.indexOf(random_number) == -1) {
          // Yay! new random number
          unique_random_numbers.push(random_number);
        }
      }
      return unique_random_numbers;
    };

    var ourRandoms = getRandomNumbers(4, jsonResponseLength);

Async Module Callbacks

## In primary file

```
const otherFile = require("./some-async-shit");

let key = 15;

let getBookData = function(err, data) {
  console.log(data, (data += 10));
};
otherFile.getYuge(key, getBookData);
```
## In module file

```
let getYuge = function(numss, callback) {
  setTimeout(() => {
    let yugeness = (numss *= 100);
    callback(null, yugeness);
  }, 1000);
};

module.exports.getYuge = getYuge;

```

K8s List all resources in all namespaces

kubectl get $(kubectl api-resources --verbs=list -o name | paste -sd, -) --ignore-not-found --all-namespaces

vim column wrap

:set nowrap 


:%!column -t

Scheduled download from HTTP folder

Set of scripts used to download pictures from a WiFi SD card
schtasks /create /sc minute /mo 1 /tn "SD wifi download" /tr c:\Users\Vaio\Downloads\wifitest\bat\wifidump.bat

two tone background

.element {
  background: linear-gradient(135deg, #234474 0%, #234474 20%, #3b8da8 20%, #3b8da8 100%) !important;
}

.three-colors {
  background: linear-gradient(135deg, #234474 0%, #234474 20%, #3b8da8 20%, #3b8da8 80%, #ffffff 80%, #ffffff 100%);
}

// you can create multiple shapes by layering gradients and using transparency to allow other layers to show through

shortcode list pages by id

function paginas_id($atts) {
  ob_start();
  $a = shortcode_atts( array(
    'id' => '',
  ), $atts );  

      $id_array = explode(',', $a['id']);
 
			global $post; 
			$args = array(              
				'post_type'      => 'page',
				'posts_per_page' => -1,
				'order'          => 'ASC',
        'orderby'        =>'meta_value_num',
        'post__in'       => $id_array,
			); 
      $query = new WP_Query( $args );  
      if ( $query->have_posts() ) :   
				while ( $query->have_posts() ) : $query->the_post();
					echo '<p class="lista-paginas-irmas"><a href="'.get_the_permalink().'">';					
						echo get_the_title();					
					echo '</a></p>';
        endwhile;   
      endif; 
			wp_reset_postdata();  
			
  $content = ob_get_contents();
  ob_end_clean();
  return $content;
}
add_shortcode('paginas-por-id', 'paginas_id');

Escape HTML from string

<?php
function escape(string $input):string {
  return preg_replace('/<\s*[^>]*>(.*?)/', ' ', $input);
}

GravityForms: change notifications format to MULTIPART

add_filter( 'gform_notification', 'change_notification_format', 10, 3 );
function change_notification_format( $notification, $form, $entry ) {
	GFCommon::log_debug( 'gform_notification: change_notification_format() running.' );
	// Do the thing only for a notification with the name Text Notification

	GFCommon::log_debug( 'gform_notification: format changed to multipart.' );
	// Change notification format to multipart from the default html
	$notification['message_format'] = 'multipart';

	return $notification;
}

Fill into form field value from a cookie

/* START code for fill into field value from a cookie */
<script src="http://instapagesupport.com/scripts/js.cookie.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() { 
    var cookieValue = Cookies.get('Cookie name');  
    var fieldName = 'Cookie value is:';
    var fieldLabel =  window.__page_generator ? fieldName : base64_encode(fieldName); 
    document.querySelector("input[name='" + fieldLabel + "']").value = cookieValue;  
});
</script>
/* END code for fill into field value from a cookie */

Remove duplicates

# Remove duplicates

> The following query has to be executed multiple times unti 0 rows are affected.

```sql
WHERE id IN (
		SELECT
			MIN(id)
			FROM tracking_number
		GROUP BY
			number
		HAVING
			COUNT(*) > 1);
```

service.spec.ts

import { async, TestBed, inject } from '@angular/core/testing'
import {
    HttpClientTestingModule,
    HttpTestingController
} from '@angular/common/http/testing'

import { AccountsService } from './accounts.service'
import { UserService } from '@shared/core/services/user.service'
import { AccountModel } from '../Models/account.model'
import { of, Observable } from 'rxjs'
import { User } from '@shared/core/models/user.model'
import { HttpRequest } from '@angular/common/http'

const mockAccountEntities = [
    {
        accountEntityId: 1,
        tenantId: 'E4256D18-3194-48D8-838A-36EF6F73EAD4',
        accountId: 1,
        name: 'Mi Group/Square',
        status: 'Active',
        alias: 'IR',
        website: null,
        industry: 'Moving',
        code: 'IR',
        address: {
            address1: '100 Bayview Circle',
            address2: '250',
            address3: null,
            city: 'Newport Beach',
            state: 'California',
    

Sample angular service methods

getAccounts() {
        this.token = this._userService.getBearerToken()
        // console.log(this.token)

        const headers = new HttpHeaders({
            'Content-Type': 'application/json',
            Authorization: 'Bearer ' + this.token
        })

        const params = new HttpParams()
            .set('pageNumber', '1')
            .set('pageSize', '10')

        return this._httpClient
            .get<ServerListData>(this.accountEntitiesUrl, { headers, params })
            .pipe(
                tap(console.log),
                map(res =>
                    res.data.map(account =>
                        new AccountModel().fromJSON(account)
                    ) as AccountModel[]
                ),
                shareReplay(1)
            )
    }

    getAccount({
        accountId,
        accountEntityId
    }: {
        accountId: string
        accountEntityId: string
    }): Observable<AccountModel> {
        const headers = ne

parseDetailRoute

// eg detailRoute="../account/{accountId}/{accountEntityId}">

parseDetailRoute(el: PlatformBaseModel): string {
        let route = this.detailRoute
        const tokens = route.match(/\{([^}]+)\}/g).map(match => {
            return match.replace(/\{([^}]+)\}/g, '$1')
        })

        tokens.forEach(token => {
            route = route.replace(`{${token}}`, el[token])
        })
        return route
    }