Type Hero 初级篇练习题(三)———keyof、typeof和映射的对象类型

106 阅读3分钟

keyof 操作符

keyof 比较简单,是获取对象中所有键的 字面联合类型,下面举一个例子

const casettesByArtist = {
  'Alanis Morissette': 2,
  'Mariah Carey': 8,
  'Nirvana': 3,
  'Oasis': 2,
  'Radiohead': 3,
  'No Doubt': 3,
  'Backstreet Boys': 3,
  'Spice Girls': 2,
  'Green Day': 2,
  'Pearl Jam': 5,
  'Metallica': 5,
  "Guns N' Roses": 2,
  'U2': 3,
  'Aerosmith': 4,
  'R.E.M.': 4,
  'Blur': 3,
  'The Smashing Pumpkins': 5,
  'Britney Spears': 3,
  'Whitney Houston': 3,
};
// Artist 等价于下面 联合类型 Artists
type Artist = keyof casettesByArtist


type Artists = 'Alanis Morissette' | 'Mariah Carey' | 'Nirvana'
  | 'Oasis' | 'Radiohead' | 'No Doubt'| 'Backstreet Boys'
  | 'Spice Girls' | 'Green Day' | 'Pearl Jam'| 'Metallica'
  | 'Guns N\' Roses' | 'U2' | 'Aerosmith' | 'R.E.M.' | 'Blur'
  | 'The Smashing Pumpkins' | 'Britney Spears' | 'Whitney Houston'

typeof 操作符

我们知道,typesript世界类型对于javascript世界的变量,而typeof 则是连接javascript通向 typesript世界的桥梁,利于typeof 可以将 javascript 中变量(基本类型,对象)全部转为 typescript里的变量类型

image.png

const b = 'hello TypeScript'
const object = {
    name: 'qinghuayayue'
}

const fun = (a:number,b:number)=>{
    return a+ b
}

type bType = typeof b
// "hello TypeScript" 文本类型

type objectType = typeof object
//{  
// name: string;  
//}

type funType = typeof fun // (a: number, b: number) => number

### Mapped Object Types 映射对象类型

映射类型是 TypeScript 最强大和最通用的功能之一。它们使您能够通过转换现有类型的属性来创建新类型,从而使代码更加可靠、灵活和可维护。随着 TypeScript 的进一步发展,您会发现自己经常使用映射类型来解决日常生活中的类型(和数据)转换任务。

下面给出一个映射对象类型例子:

type MoviesByGenre = {
  action: 'Die Hard';
  comedy: 'Groundhog Day';
  sciFi: 'Blade Runner';
  fantasy: 'The Lord of the Rings: The Fellowship of the Ring';
  drama: 'The Shawshank Redemption';
  horror: 'The Shining';
  romance: 'Titanic';
  animation: 'Toy Story';
  thriller: 'The Silence of the Lambs';
};

type MovieInfoByGenre<T> = {
  [K in keyof T]: T[K];
};

type Example = MovieInfoByGenre<MoviesByGenre>;

调用映射对象类型MovieInfoByGenre,我们创建了一个和MoviesByGenre一样的 Example类型,当然在遍历时,我们也可以对MoviesByGenre每个元素进行加工。

例题

给出一个MovieInfoByGenre类型,让其满足下面测试用例

type MovieInfoByGenre = unknown;

type MoviesByGenre = {
  action: 'Die Hard';
  comedy: 'Groundhog Day';
  sciFi: 'Blade Runner';
  fantasy: 'The Lord of the Rings: The Fellowship of the Ring';
  drama: 'The Shawshank Redemption';
  horror: 'The Shining';
  romance: 'Titanic';
  animation: 'Toy Story';
  thriller: 'The Silence of the Lambs';
};

const test_MoviesInfoByGenre: MovieInfoByGenre<MoviesByGenre> = {
  action: {
    name: 'Die Hard',
    year: 1988,
    director: 'John McTiernan',
  },
  comedy: {
    name: 'Groundhog Day',
    year: 1993,
    director: 'Harold Ramis',
  },
  sciFi: {
    name: 'Blade Runner',
    year: 1982,
    director: 'Ridley Scott',
  },
};

type test_MovieInfoByGenre = Expect<Equal<
  MovieInfoByGenre<MoviesByGenre>,
  {
    action: {
        name: string;
        year: number;
        director: string;
    };
    comedy: {
        name: string;
        year: number;
        director: string;
    };
    sciFi: {
        name: string;
        year: number;
        director: string;
    };
  }
>>;

很明显我们,对其加工一下就好了。

type MovieInfoByGenre<T,> = {
	[K in keyof T]:{
		name:string,
		year:number,
		director:string
	}
} ;

总结

Type Hero 初级篇就学完了,一共14道题,其中泛型类型,泛型函数参数变量,以及keyof,映射类型是比较有收获的内容部分。其他的文本类型、类型别名、基本数据类型都相对比较简单。因为我是先学习javascript,再学习typescript,所以最难理解的还是typescriptjavascript语法不同这块。包括平时工作也很少用到泛型,通过练习题让我对这块有了更深认识,后面也把这些运用到工作,学有所用,才是学习最终目的,最后希望我写内容对像我一样初学者有所帮助^^。