ES2015 + поток: самозаверяющие (круглые?) Перечисления - PullRequest
0 голосов
/ 29 мая 2018

Использование rollup, buble, flow-remove-types,

Возможно ли создать ENUM экземпляров классов для представления шахматной доски в виде типов, например:

// a Ref is a class or a type
class Ref { /* ... */ }

// Refs is an ENUM
Refs.forEach((ref: Ref, key: string) => {
 console.log(key) // outputs: "a1", ..., "h8" successively
}) 

// type checking should work
typeof Refs.a1 === Ref // true
// etc...
typeof Refs.h8 === Ref // true 

// move(ref) --> ref will work
Refs.a1.move(7, 7) === Refs.h8 // true
Refs.h8.move(-7, -7) === Refs.h8 // true

// with...
Refs.a1.move(0, 0) === Refs.a1 // true

// void reference
Refs.a1.move(-1, -1) === null
// or
Refs.a1.move(-1, -1) === Refs.EMPTY

Возможной модульной реализацией будет упаковка класса Ref и коллекции Refs в один файл с кодом инициализации, как это делает Enuify lib ... Но как заставить метод Ref # move работать правильно?

Так же, как:

TicTacToe.X.us =TicTacToe.X
TicTacToe.X.them =TicTacToe.O 
TicTacToe.O.us =TicTacToe.O
TicTacToe.O.them =TicTacToe.X  

1 Ответ

0 голосов
/ 05 июня 2018

как-то так, перфектно, но у меня отлично работает ...

type TF = 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'
type TR = '1'|'2'|'3'|'4'|'5'|'6'|'7'|'7'

type TRefDef = {
  file: TF,
  fidx: number,
  rank: TR,
  ridx: number
}

interface IRef {
  move (df: number, dr: number) : IRef
}

const FILES: Array <TF> = 'abcdefgh'.split('')
const RANKS: Array <TR> = '12345678'.split('')

const all: {
  [key:string] : IRef
} = {}

const compute = function(fidx: number, ridx: number): IRef {
  const file: TF = FILES[fidx]
  const rank: TR = RANKS[ridx]

  return all[file + rank]
}

const select = function(key: string) : IRef {
  return all[key]
}

const get = function(arg1: string | number, arg2: ?number) : IRef {
  if(arguments.length ===  1) {
    return select (arg1)
  }

  if(arguments.length ===  2) {
    return compute (arg1, arg2)
  }
}

const each  = function (callback) {
  Object.keys(all).forEach((key, idx) => {
    callback.call(this, all[key], idx)
  })
}

class Ref implements IRef {

  constructor (refdef: TRefDef) {
    this.file = refdef.file
    this.fidx = refdef.fidx
    this.rank = refdef.rank
    this.ridx = refdef.ridx

    this.key = this.file + this.rank
  }

  toString() : string {
    return 'Ref: ' + '(' + this.fidx + ',' + this.ridx + ')' + ' ' + this.file + this.rank
  }

  move (df: number, dr: number) : Ref {
    let f = FILES.indexOf(fidx)
    let r = RANKS.indexOf(ridx)

    f += df
    r += dr

    return all[FILES[f] + RANKS[r]]
  }
}

FILES.forEach((file, fidx) => {
  RANKS.forEach( (rank, ridx) => {
    const key: string = file + rank
    const ref: Ref = new Ref({ file, fidx, rank, ridx })

     all[key] = ref
  })
})


Ref.empty = new Ref('', -1, '', -1)

const Refs = { compute, select, each, get }
// let  f = { compute, each, selection  }
// console.log(f)

// export  { compute, each, select, Ref  }
export  { Refs, Ref  }
...