typescript shareReplay()

share-replay
Let o = new Observable (observer ={
  Observer.next('val')
}).pipe( shareReplay() );

typescript helloTypeScript

hello.ts
/* Three Basic Types in TypeScript */

let isDone: boolean = false;
let lines: number = 42;
let firstName: string = "Aayush";

/* Using Derived from Variables */
let derivedIsDone = false;
let derivedLines = 42;
let derivedfirstName = "Anders";

/* Use const keyword for Constants */
const numCats = 23;
numCats = 25;

typescript 插入前在数组中查找重复的最佳方法

保存自https://stackoverflow.com/questions/47919716/javascript-checking-duplicate-before-insert-into-array

arrayDup
  var found = datasetarr.find(o => o.accountID === receiptlist[i].accountID && o.subtype === ritemlist[k].type)
     if (found === undefined){
         //do computation
     }

typescript 复制对象数组

copy the object array
let allOrder = this.originalOrders.map(x => Object.assign({}, x));

typescript TypeScript HOC

index.ts
import React, { FC, CSSProperties } from 'react'
import { string, number, object, shape } from 'prop-types'
import { getTheme, GetThemeProps } from '@dcf/theme'

import { baseIcons } from './iconMapping'

type P = {
  icon: string
  size?: number
  viewBox?: string
  style?: CSSProperties
  config?: { icons: any }
  className?: string
} & GetThemeProps

export const IconComponent: FC<P> = ({
  theme,
  icon,
  size = theme && theme.defaultIconSize,
  viewBox = '0 0 150 150',
  style = {},
  config = { icons: {} },
  className,
}) => {
  // Merge the config object with base icons. Overwrite base icons if needed
  const icons = { ...baseIcons, ...config.icons }

  const IconComponentToRender = icons[icon]
  if (!IconComponentToRender) {
    return null
  }

  // Theme is null unless using the HOC. The editor also renders the theme null randomly sometimes even when it calls the HOC ¯\_(ツ)_/¯
  const combinedStyle = { stroke: theme && theme.defaultIconColor, ...style }

  return (
    <IconComponentToRender
      className={className}
      width={size}
      height={size}
      viewBox={viewBox}
      style={combinedStyle}
    />
  )
}

IconComponent.propTypes = {
  icon: string.isRequired,
  size: number,
  viewBox: string,
  style: object,
  config: shape({
    icons: object.isRequired,
  }),
  className: string,
}

export const Icon = getTheme<P>(IconComponent)

typescript TypeScript Snippets #typescript

TypeScript Snippets #typescript

ts.ts
interface ValidatorFn {
  {c: AbstractControl: ValidationErrors|null
}

typescript vanilaで复数スタイル

setStyles.ts
const reUnit = /width|height|top|left|right|bottom|margin|padding/i

type setStyleProps = {
  node: HTMLElement
  att: string
  val: string
  style: {}
}

const setStyle = ({ node, att, val, style }: setStyleProps) => {
  style = style || node.style

  if (style) {
    if (val === null || val === '') {
      val = ''
    } else if (!isNaN(Number(val)) && reUnit.test(att)) {
      val += 'px'
    }

    if (att === '') {
      att = 'cssText'
      val = ''
    }

    style[att] = val
  }
}

export const setStyles = (el: HTMLElement, hash: CSSStyleDeclaration) => {
  const hasCSSTextFeature = typeof el.style.cssText !== 'undefined'

  let originStyleText
  const originStyleObj = {}

 hasCSSTextFeature
  ? originStyleText = el.style.cssText
  : originStyleText = el.getAttribute('style')

  originStyleText!.split(';').forEach(item => {
    if (item.indexOf(':') !== -1) {
      const obj = item.split(':')
      originStyleObj[obj[0].trim()] = obj[1].trim()
    }
  })

  const styleObj = {}

  Object.keys(hash).forEach(item => setStyle({
    node: el,
    att: item,
    val: hash[item],
    style: styleObj
  }))

  const mergedStyleObj = Object.assign({}, originStyleObj, styleObj)
  const styleText = Object.keys(mergedStyleObj)
    .map(item => item + ': ' + mergedStyleObj[item] + ';')
    .join(' ')

 hasCSSTextFeature
  ? el.style.cssText = styleText
  : el.setAttribute('style', styleText)
}

typescript 卢拉斯头脑风暴

1 - usage.ts
const a = new Life();
a.pos = new Vector(10, 10);

a.setParameter(Parameter.ENERGY, 100);
a.setParameter(Parameter.WEIGHT, 1);
a.setParameter(Parameter.FOOD, x => x.hasParameter(Parameter.IS_PLANT));

a.addSense(new Sight({ radius: 10, angle: 270, precision: 1 }))
a.addSense(new Hearing({ radius: 1, angle: 360,  })

a.addBehaviour(new FlockingBehaviour(), { intensity: 0.5 });
a.addBehaviour(new PredatorBehaviour(), { intensity: 1 });
a.addBehaviour(new PeopleBehaviour(), { intensity: 0.2 });

a.tick(world);
ConstructorOf.ts
type ConstructorOf<T> = new() => T;
IBehaviour.ts
interface IBehaviour {
  tick(event: TickEvent);
  reset(); // kind of Tick destructor, to remove any cache for the tick
}
ISense.ts
interface ISense {
  sense(at: IVector, world: IWorld): Life[];
}
IVector.ts
interface IVector {
  readonly x: number;
  readonly y: number;

  multiply(value: number): IVector;
  merge(other: IVector): IVector;
}
IWorld.ts
interface IWorld {
  getEntitiesAt(center: IVector, radius: number): Life[];
}
Life.ts
class Life {
  pos: IVector;
  acceleration: IVector;
  private readonly parameters = new Map<Parameter, any>();
  private readonly senses: ISense[] = [];
  private readonly behaviours = new Map();

  setParameter(param: Parameter, value: any) {
    this.parameters.set(param, value);
  }

  getParameter<T>(param: Parameter) {
    return this.parameters.get(param) as T;
  }

  addSense(sense: ISense) {
    this.senses.push(sense);
  }

  getSenses() {
    return this.senses;
  }

  addBehaviour(behaviour: IBehaviour, { intensity }: { intensity: number } = { intensity: 1 }) {
    this.behaviours.set(behaviour.constructor, {
      implementation: behaviour,
      intensity
    });
  }

  getBehaviour<T>(Class: ConstructorOf<T>): T {
    const entry = this.behaviours.get(Class);
    return entry && entry.implementation;
  }

  shove(force) {
    this.acceleration = this.acceleration.merge(force);
  }

  tick(world: IWorld) {
    // Can be cached
    const event = new TickEvent(this, world);

    this.behaviours.forEach(({ implementation, intensity }) => {
      event.intensity = intensity;
      implementation.tick(event);
    });

    const force = event.getWillForce();
    if (force) {
      this.shove(force);
    }
  }

  reset() {
    this.behaviours.forEach(({ implementation }) => implementation.reset());
  }
}
Parameter.ts
enum Parameter {
  ENERGY,
  WEIGHT,
  FOOD,
  IS_PLANT,
}
SampleBehaviour.ts
class FlockingBehaviour implements IBehaviour {

  private _isFlocking = false;
  get isFlocking() {
    return this._isFlocking;
  }

  tick(event: TickEvent) {
    const neighbors = event.useSenses();
    const flockings = neighbors
      .map(x => x.getBehaviour(FlockingBehaviour))
      .filter(Boolean);
    
    if (flockings.some(x => x.isFlocking)) {
      this._isFlocking = true;
      ...
      event.setWill(flockingDirection);
    }
  }
  
  reset() {
    this._isFlocking = false;
  }
}
TickEvent.ts
class TickEvent {
  intensity = 1;
  private readonly pushes: IVector[] = [];

  constructor(
    private readonly self: Life,
    private readonly world: IWorld
  ) {}

  useSenses(): Life[] {
    const senses = this.self.getSenses();
    return senses.flatMap(x => x.sense(this.self.pos, this.world));
  }

  setWill(force: IVector) {
    this.pushes.push(force.multiply(this.intensity));
  }

  getWillForce() {
    return this.pushes.reduce((a, b) => a.merge(b));
  }
}

typescript 检查值是否为空

检查值是否为空

utils.ts
export class Utils {
  /**
   * @static
   * @param {*} value
   * @param {*} [strict=false]
   * @returns {boolean}
   * @memberof Utils
   *
   * Under the rule of strict the values of object and arrays will be checked as well
   * Also Number 0 under strict will return false
   * Example:
   *    Utils.IsEmpty(['', '', {}, [{}]]) === true;
   */
  static IsEmpty(value: any, strict: any = false): boolean {
    if (typeof strict !== 'boolean') {
      strict = false;
    }
    const type = (typeof value).toLocaleLowerCase();
    if (type !== 'number' && !Boolean(value)) {
      return true;
    }
    switch (type) {
      case 'object':
        if (Array.isArray(value)) {
          if (strict) {
            return value.every(arrayValue => Utils.IsEmpty(arrayValue));
          }
          return Boolean(value.length === 0);
        }
        if (strict) {
          return Object.keys(value)
              .filter(objectKey => Boolean(value[objectKey]))
              .every(objectKey => Utils.IsEmpty(value[objectKey]));
        }
        return Boolean(Object.keys(value).length === 0);
      case 'string':
        return Boolean(value.length === 0);
      case 'number':
        return strict ? false : Boolean(value);

      default:
        return false;
    }
  }

  static NotEmpty(value: any): boolean {
    return !Utils.IsEmpty(value);
  }

  static IsEmptyDeep(value: any): boolean {
    return Utils.IsEmpty(value, true);
  }

  static NotEmptyDeep(value: any): boolean {
    return !Utils.IsEmptyDeep(value);
  }
}

typescript Анимация,атрибутыидр。

Клонирование,добавление,перемещениеэлементов»»ноподробно。

jQuery_13.js
$(document).ready(function () {

    // ### Базовая анимация
    // Можно использовать со словами либо конкретно в миллисекундах.
    // Способ 1:
    $('.box:first').hide(1000)
    // Способ 2:
    $('.box:first').delay(1000).hide(1000)
    // Способ 3:
    $('.box:first').delay(1000).hide(1000).delay(1000).show(1000)
    // Способ 4:
    $('.box:first').delay('slow').hide('fast').delay(1000).show(1000)
    // Способ 5:
    // Позволяет анимировать 1 из атрибутов:
    $('.box:first').animate({ 'width': '200px' }, 1000)
    // Способ 6:
    // Элемент сомкнётся уменьшаясь в размере:
    $('.box:first').slideUp(1000)
    // Способ 7:
    // Элемент пропадёт и обратно появится:
    $('.box:first').slideUp(1000).slideDown(1000)

});
jQuery_14.js
$(document).ready(function () {

    // ### Взаимодействие с атрибутами.
    // Узнать атрибут пути к картинке:
    // Способ 1:
    alert($('img').attr('src'));
    // Способ 2:
    // Делаем типо слайдер. Вторая по счёту function и поменяет на другую картинку:
    $('img').click(function(){
     $(this).fadeOut(500, function({
         $(this).attr('src', 'img2.jpg').fadeIn(500);
     });   
    });
    // Способ 3:
    // Тэг 'p' у которого класс lead, ему добавим атрибут data-target и в нём будет text.
    // Таким образом можно сделать той или иной атрибут динамическим (можем вешать свои, считывать чужие)!
    $('p.lead').attr('data-target', 'text')
    
});
jQuery_15.js
$(document).ready(function () {

    // ### Взаимодействие с классами.
    // Способ 1:
    // Прибавим к уже имеющему классу класс, результат - "lead blue". Текст станет в итоге синим!
    $('p.lead').addClass('blue')
    // Способ 2:
    // При клике текст станет синим.
    $('.lead').click(function () {
        $('p.lead').addClass('blue')
    });
    // Способ 3:
    // Удалить класс.
    $('.lead').click(function () {
        $(this).removeClass('lead')
    });
    // Способ 4:
    // Делаем класс динамическим (то есть blue будет то прибавляться то убираться).
    $('.lead').click(function () {
        $(this).toggleClass('blue')
    });
    // Способ 5:
    // Делаем класс динамическим (заменит сам класс lead на blue).
    $('.lead').click(function () {
        $(this).toggleClass('lead', 'blue')
    });

});
jQuery_16.js
$(document).ready(function () {

    // ### Клонирование, добавление, перемещение элементов.
    $('.lead').click(function () {
        // Способ 1:
        $(this).text('Можем вставить свой текст');
        // Способ 2:
        $(this).html('Можем вставить свой <em>текст</em>');
        // Способ 3:
        $(this).append(' Можем добавить какой то текст в конце');
        // Способ 4:
        $(this).prepend('Добавим текст в начало. ');
        // Способ 5:
        $(this).after('<p>Текст на новом абзаце.</p>');
        // Способ 6:
        // Тэг <p class"lead"> обернём "div"-ом (если кликать на текст то оборачивает безконечно).
        $(this).wrap('<div class="container"></div>');
        // Способ 7:
        // Убрать обёртку.
        $(this).unwrap('<div class="wrap"></div>');
        // Способ 8:
        // Убрать содержимое тэга.
        $(this).empty();
        // Способ 9:
        // Удалить тэг вместе с содержимым!
        $(this).remove();
        // Способ 10:
        // Клонировать
        $(this).append('<br />' + $(this).text());

    })

});