标签:typescript 高级类型
一 , 交叉类型(操作符 & ):
代码 :
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U>{};
for (let id in first) {
(<any>result)[id] = (<any>first)[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
class Person {
constructor(public name: string) { }
}
interface Loggable {
log(): void;
}
class ConsoleLogger implements Loggable {
log() {
console.log(`AAAAA`);
}
}
let jim = extend(new Person("Jim"), new ConsoleLogger());
let n = jim.name;
console.log(`this is name : ${n}`);
jim.log();编译及结果:
可以看出jim既有Person的成员 , 也有ConsolerLogger的成员 . 交叉类型既是将此2种类型合并在一起使用:编译成的JS如下:
function extend(first, second) {
var result = {};
for (var id in first) {
result[id] = first[id];
}
for (var id in second) {
if (!result.hasOwnProperty(id)) {
result[id] = second[id];
}
}
return result;
}
var Person = (function () {
function Person(name) {
this.name = name;
}
return Person;
}());
var ConsoleLogger = (function () {
function ConsoleLogger() {
}
ConsoleLogger.prototype.log = function () {
console.log("AAAAA");
};
return ConsoleLogger;
}());
var jim = extend(new Person("Jim"), new ConsoleLogger());
var n = jim.name;
console.log("this is name : " + n);
jim.log();二,联合类型(操作符 | )
abstract class Monster{
public tpid : number;
public name : string;
public abstract attack:()=>string;
constructor( tpid : number , name : string ){
this.tpid = tpid;
this.name = name;
}
}
class Godzilla extends Monster{
constructor(tpid : number){
super( tpid , `Godzilla` );
}
//实现attack方法
public attack:()=>string=function(){
return `id : ${this.tpid} ,name : ${this.name} -> can fire`;
}
}
class Medusa extends Monster{
constructor(tpid : number){
super(tpid,`Medusa`);
}
public attack:()=>string=function(){
return `id : ${this.tpid} , name : ${this.name} -> can turn to stone`;
}
}
enum Monster_Type{
Godzilla = 0,//哥斯拉
Medusa = 1,//美杜莎
}
//!important
//使用联合类型
//因为返回参数可能是哥斯拉 也可能是美杜莎 所以使用联合类型(多选一)
let create_monster : ( type : Monster_Type , tpid : number ) => Godzilla | Medusa = function( ty , id ){
switch ( ty ){
case Monster_Type.Godzilla:
return new Godzilla(id);
case Monster_Type.Medusa:
return new Medusa(id);
}
return null;
};
let gsl : Godzilla = create_monster( Monster_Type.Godzilla , 1 );
console.log( `gsl :: ${gsl.attack()}` );
let mds : Medusa = create_monster( Monster_Type.Medusa , 2 );
console.log( `mds :: ${mds.attack()}` );上述代码 : create_monster方法的返回类型使用了联合类型
得到结果:
做一个测试 , 如果联合参数列表中没有AA类型 , 如果我们强制返回AA:
abstract class Monster{
public tpid : number;
public name : string;
public abstract attack:()=>string;
constructor( tpid : number , name : string ){
this.tpid = tpid;
this.name = name;
}
}
class Godzilla extends Monster{
constructor(tpid : number){
super( tpid , `Godzilla` );
}
//实现attack方法
public attack:()=>string=function(){
return `id : ${this.tpid} ,name : ${this.name} -> can fire`;
}
}
class Medusa extends Monster{
constructor(tpid : number){
super(tpid,`Medusa`);
}
public attack:()=>string=function(){
return `id : ${this.tpid} , name : ${this.name} -> can turn to stone`;
}
}
class AA{
}
enum Monster_Type{
Godzilla = 0,//哥斯拉
Medusa = 1,//美杜莎
AA = 2
}
//使用联合类型(AA并没有被加入到联合类型 (返回类型中)) Error
//因为返回参数可能是哥斯拉 也可能是美杜莎 所以使用联合类型(多选一)
let create_monster : ( type : Monster_Type , tpid : number ) => Godzilla | Medusa = function( ty , id ){
switch ( ty ){
case Monster_Type.Godzilla:
return new Godzilla(id);
case Monster_Type.Medusa:
return new Medusa(id);
case Monster_Type.AA:
return new AA();
}
return null;
};
let gsl : Godzilla = create_monster( Monster_Type.Godzilla , 1 );
console.log( `gsl :: ${gsl.attack()}` );
let mds : Medusa = create_monster( Monster_Type.Medusa , 2 );
console.log( `mds :: ${mds.attack()}` );编译报错:
这里需要注意一点 : 代码如下
abstract class Monster{
public tpid : number;
public name : string;
public abstract attack:()=>string;
constructor( tpid : number , name : string ){
this.tpid = tpid;
this.name = name;
}
}
/**
* 哥斯拉
*/
class Godzilla extends Monster{
constructor(tpid : number){
super( tpid , `Godzilla` );
}
//实现attack方法
public attack:()=>string=function(){
return `id : ${this.tpid} ,name : ${this.name} -> can fire`;
}
//实现喷火技能
public fire:()=>string=function(){
return `i can breathe fire`;
}
}
/**
* 美杜莎
*/
class Medusa extends Monster{
constructor(tpid : number){
super(tpid,`Medusa`);
}
//实现attack方法
public attack:()=>string=function(){
return `id : ${this.tpid} , name : ${this.name} -> can turn to stone`;
}
//实现石化技能
public stone:()=>string=function(){
return `I can turn you into a stone`;
}
}
/**
* 怪物类型枚举
*/
enum Monster_Type{
Godzilla = 0,//哥斯拉
Medusa = 1//美杜莎
}
//使用联合类型
//因为返回参数可能是哥斯拉 也可能是美杜莎 所以使用联合类型(多选一)
let create_monster : ( type : Monster_Type , tpid : number ) => Godzilla | Medusa = function( ty , id ){
switch ( ty ){
case Monster_Type.Godzilla:
return new Godzilla(id);
case Monster_Type.Medusa:
return new Medusa(id);
}
return null;
};
/*
function create_monster( type : Monster_Type , tpid : number ) : Godzilla | Medusa{
switch ( type ){
case Monster_Type.Godzilla:
return new Godzilla(tpid);
case Monster_Type.Medusa:
return new Medusa(tpid);
}
return null;
}
*/
let gsl = create_monster( Monster_Type.Godzilla , 1 );
console.log( `gsl :: ${gsl.attack()}` );
let mds : Medusa = create_monster( Monster_Type.Medusa , 2 );
console.log( `mds :: ${mds.attack()}` );编译报错如下:
解决方案有2种 :
① , 将 ":Medusa"去掉(如上图) , 因为Godzilla类和Medusa类不兼容 . 而返回类型使用了联合类型.如果有"Medusa" ,他会检测 Godzilla类和Medusa类的兼容性而报错.
② , 将Godzilla类里面的方法fire 及 Medusa里面的方法stone去掉,以使他们兼容 . 这时可以将":Medusa"加上.
三,保护类型
abstract class Monster{
public tpid : number;
public name : string;
public abstract attack:()=>string;
constructor( tpid : number , name : string ){
this.tpid = tpid;
this.name = name;
}
}
/**
* 哥斯拉
*/
class Godzilla extends Monster{
constructor(tpid : number){
super( tpid , `Godzilla` );
}
//实现attack方法
public attack:()=>string=function(){
return `id : ${this.tpid} ,name : ${this.name} -> can fire`;
}
//实现喷火技能
public fire:()=>string=function(){
return `i can breathe fire`;
}
}
/**
* 美杜莎
*/
class Medusa extends Monster{
constructor(tpid : number){
super(tpid,`Medusa`);
}
//实现attack方法
public attack:()=>string=function(){
return `id : ${this.tpid} , name : ${this.name} -> can turn to stone`;
}
//实现石化技能
public stone:()=>string=function(){
return `I can turn you into a stone`;
}
}
/**
* 怪物类型枚举
*/
enum Monster_Type{
Godzilla = 0,//哥斯拉
Medusa = 1//美杜莎
}
//使用联合类型
//因为返回参数可能是哥斯拉 也可能是美杜莎 所以使用联合类型(多选一)
let create_monster : ( type : Monster_Type , tpid : number ) => Godzilla | Medusa = function( ty , id ){
switch ( ty ){
case Monster_Type.Godzilla:
return new Godzilla(id);
case Monster_Type.Medusa:
return new Medusa(id);
}
return null;
};
/*
function create_monster( type : Monster_Type , tpid : number ) : Godzilla | Medusa{
switch ( type ){
case Monster_Type.Godzilla:
return new Godzilla(tpid);
case Monster_Type.Medusa:
return new Medusa(tpid);
}
return null;
}
*/
let gsl = create_monster( Monster_Type.Godzilla , 1 );
//console.log( `gsl :: ${gsl.attack()}` );
//
let mds = create_monster( Monster_Type.Medusa , 2 );
//console.log( `mds :: ${mds.attack()}` );
console.log((<Godzilla>gsl).fire());//(<Godzilla>gsl).fire
console.log((<Medusa>mds).stone());结果:
如上述代码 :
let gsl = create_monster( Monster_Type.Godzilla , 1 );
let mds = create_monster( Monster_Type.Medusa , 2 );
gsl 及 mds 都没有类型的声明. 如果要调用他们的技能 , gsl只能调用fire方法 , 而mds只能调用stone方法.我们程序员可以给这样的类型一个相当于强制装换的方案 如 : (<Godzilla>gsl).fire这样的写法很少见.记住就好.
四,索引类型:
function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
return names.map(n => o[n]);
}
interface Person {
name: string;
age: number;
add:( x : number , y : number ) => number;
}
let person: Person = {
name: ‘Jarid‘,
age: 35,
add:( x : number , y : number )=>{ return x + y ;},
};
let strings: Function[] = pluck(person, [‘add‘]);
console.log( ` ${ strings[0](1,2) } ` );结果:
keyof T 返回T的公共成员联合 , 如:
function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
return names.map(n => o[n]);
}
interface Person {
name: string;
age: number;
add:( x : number , y : number ) => number;
}
let person: Person = {
name: ‘Jarid‘,
age: 35,
add:( x : number , y : number )=>{ return x + y ;},
};
let strings: Function[] = pluck(person, [‘add‘]);
//console.log( ` ${ strings[0](1,2) } ` );
//获取属性值
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
return o[name]; // o[name] is of type T[K]
}
let a : string = getProperty( person , ‘name‘ );
console.log(a);
let b : Function = getProperty( person , ‘add‘ );
console.log( `${b(2,3)}` );结果:
本文出自 “Better_Power_Wisdom” 博客,请务必保留此出处http://aonaufly.blog.51cto.com/3554853/1956138
标签:typescript 高级类型
原文地址:http://aonaufly.blog.51cto.com/3554853/1956138