TS语言学习(二)
一、类型别名
TypeScript 提供了为类型注解设置别名的便捷语法,你可以使用 type SomeName = someValidTypeAnnotation 来创建别名,比如:
type Pet = 'cat' | 'dog';
let pet: Pet;
pet = 'cat'; // Ok
pet = 'dog'; // Ok
pet = 'zebra'; // Compiler error
二、基础知识
为了让大家能更好地理解并掌握 TypeScript 内置类型别名,我们先来介绍一下相关的一些基础知识。
2.1 typeof
在 TypeScript 中, typeof 操作符可以用来获取一个变量声明或对象的类型。
interface Person {
name: string;
age: number;
}
const sem: Person = { name: 'semlinker', age: 30 };
type Sem= typeof sem; // -> Person
function toArray(x: number): Array {
return [x];
}
type Func = typeof toArray; // -> (x: number) => number[]
2.2 keyof
keyof 操作符可以用来一个对象中的所有 key 值:
interface Person {
name: string;
age: number;
}
type K1 = keyof Person; // "name" | "age"
type K2 = keyof Person[]; // "length" | "toString" | "pop" | "push" | "concat" | "join"
type K3 = keyof { [x: string]: Person }; // string | number
2.3 in
in 用来遍历枚举类型:
type Keys = "a" | "b" | "c"
type Obj = {
[p in Keys]: any
} // -> { a: any, b: any, c: any }
2.4 infer
在条件类型语句中,可以用 infer 声明一个类型变量并且对它进行使用。
type ReturnType = T extends (
...args: any[]
) => infer R ? R : any;
以上代码中 infer R 就是声明一个变量来承载传入函数签名的返回值类型,简单说就是用它取到函数返回值的类型方便之后使用。
2.5 extends
有时候我们定义的泛型不想过于灵活或者说想继承某些类等,可以通过 extends 关键字添加泛型约束。
interface ILengthwise {
length: number;
}
function loggingIdentity(arg: T): T {
console.log(arg.length);
return arg;
}
现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:
loggingIdentity(3); // Error, number doesn't have a .length property
这时我们需要传入符合约束类型的值,必须包含必须的属性:
loggingIdentity({length: 10, value: 3});
三、内置类型别名
3.1 Partial
Partial
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Make all properties in T optional
*/
type Partial = {
[P in keyof T]?: T[P];
};
在以上代码中,首先通过 keyof T 拿到 T 的所有属性名,然后使用 in 进行遍历,将值赋给 P ,最后通过 T[P] 取得相应的属性值。中间的 ? ,用于将所有属性变为可选。
示例:
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: "organize desk",
description: "clear clutter"
};
const todo2 = updateTodo(todo1, {
description: "throw out trash"
});
3.2 Required
Required
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Make all properties in T required
*/
type Required = {
[P in keyof T]-?: T[P];
};
以上代码中, -? 的作用就是移除可选项 ? 。
示例:
interface Props {
a?: number;
b?: string;
}
const obj: Props = { a: 5 }; // OK
const obj2: Required = { a: 5 }; // Error: property 'b' missing
3.3 Readonly
Readonly
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Make all properties in T readonly
*/
type Readonly = {
readonly [P in keyof T]: T[P];
};
如果将上面的 readonly 改成 -readonly , 就是移除子属性的 readonly 标识。
示例:
interface Todo {
title: string;
}
const todo: Readonly = {
title: "Delete inactive users"
};
todo.title = "Hello"; // Error: cannot reassign a readonly property
Readonly
function freeze(obj: T): Readonly ;
3.4 Record
Record
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Construct a type with a set of properties K of type T
*/
type Record = {
[P in K]: T;
};
示例:
interface PageInfo {
title: string;
}
type Page = "home" | "about" | "contact";
const x: Record = {
about: { title: "about" },
contact: { title: "contact" },
home: { title: "home" }
};
3.5 Pick
Pick
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick = {
[P in K]: T[P];
};
示例:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
3.6 Exclude
Exclude
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Exclude from T those types that are assignable to U
*/
type Exclude = T extends U ? never : T;
如果 T 能赋值给 U 类型的话,那么就会返回 never 类型,否则返回 T 类型。最终实现的效果就是将 T 中某些属于 U 的类型移除掉。
示例:
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude void), Function>; // string | number
3.7 Extract
Extract
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Extract from T those types that are assignable to U
*/
type Extract = T extends U ? T : never;
如果 T 能赋值给 U 类型的话,那么就会返回 T 类型,否则返回 never 类型。
示例:
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract void), Function>; // () => void
3.8 Omit
Omit
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit = Pick>;
示例:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
3.9 NonNullable
NonNullable 的作用是用来过滤类型中的 null 及 undefined 类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Exclude null and undefined from T
*/
type NonNullable = T extends null | undefined ? never : T;
示例:
type T0 = NonNullable; // string | number
type T1 = NonNullable; // string[]
3.10 ReturnType
ReturnType 的作用是用于获取函数 T 的返回类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Obtain the return type of a function type
*/
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
示例:
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<() => T>; // {}
type T3 = ReturnType<() => T>; // number[]
type T4 = ReturnType蓦然JL
阅读(4)
评论(0)
编辑
刷新页面返回顶部
<script type="text/javascript">
var commentManager = new blogCommentManager();
commentManager.renderComments(0);
fixPostBody();
window.tocManager.displayDisableTocTips = false;
window.tocManager.generateToc();
setTimeout(function() { incrementViewCount(cb_entryId); }, 50); deliverT2();
deliverC1C2();
loadNewsAndKb();
LoadPostCategoriesTags(cb_blogId, cb_entryId); LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType);
loadOptUnderPost();
GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);
</script>
<script>loadBlogNews();</script>
<script>loadBlogDefaultCalendar();</script>
<script>loadBlogSideColumn();</script>
Copyright ? 2022 蓦然JL
Powered by .NET 6 on Kubernetes
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/mouse-click.js"></script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/fish.js"></script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/APlayer.js"></script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/Meting.js"></script>
<script>
let ref = setInterval(function(){
isaplay();
},2000);
function isaplay(){
if($(".aplayer-play").length == 1){
$(".aplayer-play").click()
clearInterval(ref);
}
}
</script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/blogs-custom.js"></script>
MENU
<script src="https://blog-static.cnblogs.com/files/blogs/725648/jquery.cookie.js"></script>
<script>
</script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/share.js"></script>
访问主页
关注我
?
关注微博
私信我
返回顶部
<script>
$('#share-btn').share({sites: ['qzone', 'qq', 'weibo','wechat']});
</script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/blogs-custom-nav.js"></script>
<script type="text/javascript">
$(function() {
var $navList = $('#navList');
$navList.cnblogsNav('addNav', 3, '随笔', 'https://www.cnblogs.com/moranjl/p');
$navList.cnblogsNav('addNav', 4, '文章', 'https://www.cnblogs.com/moranjl/category/2101877.html');
$navList.cnblogsNav('addNav', 5, '日记', 'https://www.cnblogs.com/moranjl/MyDiary.html');
$navList.cnblogsNav('addNav', 6, '相册', 'https://www.cnblogs.com/moranjl/p/15880536.html');
$navList.cnblogsNav('removeNav', 2);
$navList.cnblogsNav('removeNav', 7);
})
</script>
<script language="javascript" type="text/javascript">
document.onreadystatechange=function()
{
if(document.readyState=="complete")
{
$('.circle-loader-bg').hide();
$('.circle-loader').hide();
}
}
</script>
<script language="javascript" type="text/javascript">
jQuery(document).on('copy', function(e)
{
var selected = window.getSelection();
var copyFooter = '
---------------------
著作权归作者所有。
'
+ '商业转载请联系作者获得授权,非商业转载请注明出处。
'
+ '作者:moranjl
源地址:' + document.location.href
+ '
来源:博客园cnblogs
? 版权声明:本文为博主原创文章,转载请附上博文链接!';
var copyHolder = $('', {html: selected + copyFooter, style: {position: 'absolute', left: '-99999px'}});
$('body').append(copyHolder);
selected.selectAllChildren( copyHolder[0] );
window.setTimeout(function() {
copyHolder.remove();
},0);
});
</script>
<script src="https://blog-static.cnblogs.com/files/blogs/725648/blogs-catalogue-nav.js"></script>
<script type="text/javascript" language="javascript">
//Setting ico for cnblogs
var linkObject = document.createElement('link');
linkObject.rel = "shortcut icon";
linkObject.href = "https://blog-static.cnblogs.com/files/blogs/725648/claw.ico";
document.getElementsByTagName("head")[0].appendChild(linkObject);
</script>
<script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-476124-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
var kv = getGACustom();
if (kv) {
gtag('set', kv);
}
gtag('config', 'UA-476124-1');
</script>
<script defer="" src="https://hm.baidu.com/hm.js?866c9be12d4a814454792b1fd0fed295"></script>