JavaScript

[TypeScript]インターセクション型

type Product = {
    title:string;
    price:number;
};

type User = {
    name:string;
};

type Order = Product & User;

const firstOrder :Order = {
    title : "走れメロス",
    price : 512,
    name  : "John Smith",
};

console.log(firstOrder);
{ title: '走れメロス', price: 512, name: 'John Smith' }

[TypeScript]配列とタプル

string型配列

let titles: string[];

 
tuple型

let order:[number,string] = [64,"John Smith"];

 
NG

order = [128,"Jeff Mike",1024];

 
NG

console.log(order[2]);

 
ラベル付き

type Order = [id:number,title:string,price?:number,...memo:any[]];

priceはオプショナル
…memoには複数の要素が入る

NG

let firstOrder:Order  = [1];

 
OK

let secondOrder:Order = [1,"あいうえお"];

 
OK

let thirdOrder:Order  = [1,"あいうえお",1024,true,512,"かきくけこ"];

 

type Order = [id:number,title:string,price?:number,...memo:any[]];
let secondOrder:Order = [1,"あいうえお"];
let thirdOrder:Order  = [1,"あいうえお",1024,true,512,"かきくけこ"];
console.log(secondOrder);
console.log(thirdOrder);
console.log(thirdOrder[0]);
console.log(thirdOrder[1]);
console.log(thirdOrder[2]);

上記を実行すると下記が出力される

[ 1, 'あいうえお' ]
[ 1, 'あいうえお', 1024, true, 512, 'かきくけこ' ]
1
あいうえお
1024

[TypeScript]readonlyプロパティ

type Order = {
    readonly id : number;
    title : string;
    price : number;
};

 
変数

const firstOrder : Order = {
    id : 2,
    title : "あいうえお",
    price : 512,
};

 
変更OK

firstOrder.title = "かきくけこ";

 
変更NG

firstOrder.id = 3;

[TypeScript]型エイリアス

型エイリアス

type DataType = number | string;
type EventName = "click" | "hover" | "mousedown";

※型エイリアスはブロックスコープ
 
使う時

let firstDataType : DataType = 123;

 
型エイリアスのユニオン

type Team = ATeam | BTeam;
type ATeam = "john" | "jeff" | "joe";
type BTeam = "mike" | "migera" | "mika";
let partner:Team = "mike";

 
オブジェクトの時
通常

let article : {
    id    : number;
    title : string;
    body  : string;
} = {
    id    : 875,
    title : "あいうえお",
    body  : "かきくけこ",
};

 
型エイリアス

type Article = {
    id    : number;
    title : string;
    body  : string;
};
const article : Article = {
    id    : 875,
    title : "あいうえお",
    body  : "かきくけこ",
};

 
ネストパターン1

type Order = {
    id : number;
    title : string;
    price : number;
    product : {
        title : string;
        price : number;
    };
};

 
ネストパターン2

type Product = {
    title : string;
    price : number;
};
type Order = {
    id : number;
    title : string;
    price : number;
    product : Product;
};

[JavaScript]スクロール位置を保存してリロード

    /**
     * initWithScrollY
     *
     * @static
     */
    static initWithScrollY(){
        let scrollY = localStorage.getItem('scrollKey');
        if(!scrollY){
            return;
        }
        localStorage.removeItem('scrollKey');
        scrollY = Number(scrollY);
        window.scrollTo(0, scrollY);
    }
    /**
     * ローカルストレージ取得
     *
     * @static
     * @param {String} key
     * @param {Boolean} remove
     * @returns {*}
     */
    static getLS(key,remove){
        const value = localStorage.getItem(key);
        if(remove){
            localStorage.removeItem(key);
        }
        return value;
    }
    /**
     * スクロール位置を保存しつつリロード
     *
     * @static
     * @param {*} delay
     */
    static reloadWithScrollY(delay){
        if(delay){
            setTimeout(()=>{
                Utils.reloadWithScrollY();
            },delay);
        }else{
            localStorage.setItem('scrollKey',window.scrollY);
            location.reload();
        }
    }
    /**
     * ローカルストレージ保存
     *
     * @static
     */
    static setLS(key,value){
        localStorage.setItem(key,value);
    }
    /**
     * スクロール位置を保存
     *
     * @static
     */
    static setScrollYToLS(){
        localStorage.setItem('scrollKey',window.scrollY);
    }

[Shopify]BuyerJourneyでチェックアウト画面の進行をブロックする

import {
  reactExtension,
  useBuyerJourneyIntercept,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
  'purchase.checkout.block.render',
  () => <Extension />,
);

function Extension() {
    useBuyerJourneyIntercept(
        ({ canBlockProgress }) => {
            let errors = [];
            if(address.lastName?.length > 10){
                errors.push({
                    message : '姓を10文字以内で入力してください',
                    target  : '$.cart.deliveryGroups[0].deliveryAddress.lastName'
                });
            }
            /* エラーがあればブロック */
            if(canBlockProgress && errors.length){
                return {
                    behavior : 'block',
                    reason   : 'Invalid length',
                    errors   : errors
                };
            }else{
                return {
                    behavior : 'allow'
                };
            }
        }
    );
}

[JavaScript]useAppMetafields

let j,productId;
const cartLines = useCartLines();
const appMetafields = useAppMetafields();
if(appMetafields.length){
  cartLines.forEach((cartLine,i)=>{
    productId = cartLine.merchandise.product.id.split("/").pop();
    for(j=0;j<appMetafields.length;j++){
      if(appMetafields[j].target.id === productId){
        if(appMetafields[j].metafield.key === "metafieldKey" && appMetafields[j].metafield.value === "metafieldValue"){
          //処理
        }
        break;
      }
    }
  });
}

[JavaScript]オプショナルチェーン備忘録

1

const tmp = {name:"abc"};
console.log(tmp.address?.length);
undefined

 
 

2

const tmp = {name:"abc"};
console.log(tmp.address?.length+tmp.city?.length);
NaN

 
 

3

const tmp = {name:"abc"};
console.log(tmp.address?.length+tmp.city?.length > 4);
false

 
 

4

const tmp = {name:"abc"};
console.log(tmp.address?.length+tmp.city?.length == 0);
false

 
 

5

const tmp = {name:""};
console.log(tmp.name?.length+tmp.city?.length <= 1);
false

 
 

6

const tmp = {name:""};
console.log(tmp.name?.length <= 1);
true