Type Script汎型高級使用

9926 ワード

コード開発においては、汎型を使用することにより、コード多重化率と符号量の簡素化が可能となる.Type Script基礎タイプの一般利用はここで説明しません.ネット上の資料が多いです.以下の問題は文書で説明されていますが、明確な例がなく、開発中のツールのエラーはよく分かりません.記録エラーは下記の通り解決されます.
Type Scriptを使用するには汎型を使用して、次のような問題があります.
interface TestData {
	name: string;
	num: number;
}

interface test<T> {
	getData(): T;
}

abstract AbstractTest<T> implements test<T> {
	data: T
	constructor(data: T) {
		this.data = data
	}
	abstract getData(): T;
}

class ATest<TestData> extends AbstractTest<T> {
	constructor() {
		let data: TestData = {
			name: "bin",
			num: 0
		}
		super(data)
	}
	getData(): T {
		return this.data;
	}
}
コンパイル以上のコードは次のような問題があります.
タイプ"{name:string;num:number]"をタイプ"TestData"に割り当てることはできません.{name:string;num:number;}'s assignable to the constrant of type'TestData'は、but'TestData'could be instantiated with a different subtype of constrant''.ts(2322)
上の文字は:
{name:string;num:number;}は、タイプTestDataによって制約されるタイプに割り当てることができますが、TestDataは、他のサブタイプに対しても制約されることができます.
テスト角度から分析すると、Tは複数のタイプに初期化され、唯一のTestDataではないので、一意性と正確性を備えていない.
公式文書を参照して、実例は以下の通りです.
function loggingIdentity<T>(arg: T): T {
  console.log(arg.length); // Error: T doesn't have .length
  return arg;
}
    T    length,       。       ,T         length   
interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length); // Now we know it has a .length property, so no more error
  return arg;
}

loggingIdentity(3); // Error, number doesn't have a .length property
loggingIdentity({ length: 10, value: 3 });
公式文書によると、汎型を特定の属性とするには、汎型は指定の種類を引き継ぐ必要がある.以上のdemoを変更してください.
interface TestData {
	name: string;
	num: number;
}

interface test<T> {
	getData(): T;
}

abstract AbstractTest<T> implements test<T> {
	data: T
	constructor(data: T) {
		this.data = data
	}
	abstract getData(): T;
}

class ATest<T extends TestData> extends AbstractTest<TestData> {
	constructor() {
		let data: TestData = {
			name: "bin",
			num: 0
		}
		super(data)
	}
	getData(): T {
		return this.data;
	}
}

let test = ATest<TestData>()
test.getData()
これで間違いないです.dataの属性が複数あると、エラーが発生しません.
let data: = {
	name: "bin",
	num: 0,
	test: 0
}
テストの状況から見て、タイプエラーを回避するために、汎型オブジェクトに値を付与する変数の属性は、特定のタイプのすべての属性を含む必要があります.
interface A {
	a: string;
	b: number;
}
<T extends A>
T   A     
このように、コンパイルは汎型の具体的なタイプを知らないで、実行時に必要な属性を持たずにエラーが発生することを避けることができます.一般タイプの属性制約は継承によって達成されます.