質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.01%

  • Go

    418questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

  • TypeScript

    247questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Typescriptでコレクションクラスの作り方

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 238

kappazushi

score 7

前提・実現したいこと

Webpackを使ったアプリケーションで、Typescriptで配列にメソッドを生やしたいのですが、エラーが出て困っています。

質問は次の3点です。

  1. ソート後のthisをthisにアサインできないのですが、どのようにするべきでしょうか?
  2. Typescriptではどのようにコレクションを実装するべきでしょうか?
  3. lodashの箇所でキャストせずにUser[]とArray<User>をまとめる方法はないでしょうか?

因みに、やりたいことをGOで書きますと以下のような感じでになります。

type User struct{
   id int64
}
type Users []User
func (this *Users) setUser(user User) {
   this = append(this, user)
  // ソートする....
}

func main() {
  u := User{}
  us := &Users{}
  us.setUser(u);
}

発生している問題・エラーメッセージ

エラーメッセージ: 
Errro: [ts] Type 'Users' is not assignable to type 'this'.

該当のソースコード

import {
  uniqBy,
  remove,
  orderBy,
  find,
  remove,
  findIndex,
} from 'lodash';


export class User extends Object {
  id: string;
  constructor() {
    super();
  }
}

export class Users extends Array<User> {
  constructor() {
    super();

    // Set the prototype explictilly
    // see https://github.com/Microsoft/TypeScript/issues/12123#issuecomment-265014802
    Object.setPrototypeOf(this, Users.prototype);

  }

  /**
   * 1件追加
   * @param {User} user
   */
  setUser(user: User): void {
    let users = this; // 現状のコレクションをコピー
    users.push(user);
    // ソート
    users = remove<User>(users, undefined) as Users; // Errro: [ts] Type 'Users' is not assignable to type 'this'.

    users = uniqBy<User>(users, 'id') as Users;
    users = orderBy<User>(users, ['created_at'], ['asc']) as Users;    
    this.splice(0, this.length); // コレクションの初期化
    Object.assign(this, users); // コレクションを更新
  }
}

補足情報(言語/FW/ツール等のバージョンなど)

   "typescript": "2.5.2",
    "webpack": "2.4.1",
    "lodash": "4.17.4",
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

素直にメンバ変数として配列をもたせたほうが良いと思います

import {
    uniqBy,
    remove,
    orderBy,
    find,
    findIndex,
  } from 'lodash';


  export class User extends Object {
    constructor(private id: string, private created_at: Date | undefined) {
        super();
        if (created_at == undefined) {
            this.created_at = new Date();
        }
    }
  }

  export class Users  {
    list: Array<User|undefined>;
    constructor() {
        this.list = [];
    }
    public setUser(user: User | undefined) {
        let users = this.list;
        users.push(user);
        users = remove(users, undefined); 
        users = uniqBy(users,'id')
        users = orderBy(users, ['created_at'],['asc'])
        this.list = users;
    }
  }

test code

import {User, Users} from '../extendArray';

it('Users', () => {
    let users = new Users();
    // users.setUser(new User(1));
    users.setUser(new User('1', new Date('2001-10-13')));
    users.setUser(new User('1', new Date()));
    users.setUser(new User('1', new Date()));
    users.setUser(undefined);
    users.setUser(new User('15', new Date('2011-10-13')));
    users.setUser(new User('7', new Date('2011-10-12')));
    users.setUser(new User('10', new Date('2011-10-11')));
    console.log(users);

})

結果

 PASS  __test__/sample.test.ts
  ✓ Users (1ms)

  console.log __test__/sample.test.ts:14
    Users {
      list:
       [ { id: '1', created_at: 2001-10-13T00:00:00.000Z },
         { id: '10', created_at: 2011-10-11T00:00:00.000Z },
         { id: '7', created_at: 2011-10-12T00:00:00.000Z },
         { id: '15', created_at: 2011-10-13T00:00:00.000Z } ] }

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.175s, estimated 1s
Ran all test suites.

Watch Usage: Press w to show more.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Go

    418questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

  • TypeScript

    247questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。