我爱一条柴 发表于 2023-12-1 01:10:22

[TS手册学习] 04_对象类型

TS官方手册:TypeScript: Handbook - The TypeScript Handbook (typescriptlang.org)
匿名与具名

对象类型的声明可以是匿名的,也可以使用interface或type进行具名声明。
function greet(person: { name: string; age: number }) {
return "Hello " + person.name;
}interface Person {
name: string;
age: number;
}

function greet(person: Person) {
return "Hello " + person.name;
}type Person = {
name: string;
age: number;
};

function greet(person: Person) {
return "Hello " + person.name;
}可选属性 optional

使用?标记:
interface PaintOptions {
shape: Shape;
xPos?: number;
yPos?: number;
}注:使用PaintOptions声明的对象,它的xPos属性会被初步推断为number | undefined类型。
可以使用条件语句或者解构+默认值的方式收束类型,排除undefined的情况:
function paintShape(opts: PaintOptions) {
    let xPos = opts.xPos === undefined ? 0 : opts.xPos;
    // xPos 的类型为number
}function paintShape({ shape, xPos = 0, yPos = 0 }: PaintOptions) {
        // xPos 的类型为number,因为undefined会被默认值0取代
    console.log("x coordinate at", xPos);
}只读属性 readonly

interface SomeType {
    readonly prop: string;
}注:如果有一个属性的值是引用值,例如一个对象或数组,且这个属性被标记为只读(readonly),我们不能修改它的引用值,但是可以修改它的内部属性。
interface Home {
readonly resident: { name: string; age: number };
}

function visitForBirthday(home: Home) {
// 我们可以读取并且更新'home.resident'里的属性
console.log(`Happy birthday ${home.resident.name}!`);
home.resident.age++;
}

function evict(home: Home) {
// 但我们不能更新'home.resident'本身
home.resident = {
Cannot assign to 'resident' because it is a read-only property.
    name: "Victor the Evictor",
    age: 42,
};
}索引签名 index signatures

interface StringArray {
: string;
}

const myArray: StringArray = getStringArray();
const secondItem = myArray;索引的类型只能是:string,number,symbol,以及与这些类型相关的联合类型。
通常只会考虑string和number类型的索引。
注:可以同时支持string,number两种类型的索引器,但数字索引器返回的类型必须是字符串索引器返回类型的子类型。这是因为当使用数字进行索引时,JS 实际上会在索引到对象之前将其转换为字符串。于是使用100和"100"进行索引的结果是一样的。
当指定string类型索引的类型为S后,所有属性的类型都需要是S的子集。
interface NumberDictionary {
    : number;

    length: number; // ok
    name: string; // NOT ok
}这是因为当我们访问obj.a的时候,其实也是在访问obj["a"]。
在上面这个例子中,string类型索引被声明为number类型,这意味着这个对象的所有属性都是number类型,而下方name却被声明为string类型,矛盾了。
可以使用联合类型解决这个问题:
interface NumberDictionary {
    : number | string;

    length: number; // ok
    name: string; // ok
}同时,索引签名也可以设置为只读:
interface ReadonlyStringArray {
readonly : string;
}类型继承

使用extends,支持多继承:
interface Colorful {
    color: string;
}

interface Circle {
    radius: number;
}

interface ColorfulCircle extends Colorful, Circle {}

const cc: ColorfulCircle = {
    color: "red",
    radius: 42,
};交集类型 intersection types

使用&运算符获取已知的两个类型的交集。
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}

type ColorfulCircle = Colorful & Circle;将两个基本数据类型取交集会得到never。
类型继承 VS 交集类型
二者都可以产生更复杂的类型。
前者是在原有的类型的基础上添加可能未有的属性形成新属性,而后者将已有的类型进行组合。
泛型对象类型 Generic Object Types

interface Box<Type> {
contents: Type;
}

let box: Box<string>;也可以与泛型函数结合使用:
function setContents<Type>(box: Box<Type>, newContents: Type) {
box.contents = newContents;
}除了使用interface,也可以使用type别名定义泛型类型。interface一般用来声明对象类型,而type更灵活,可以组合多种类型:
type OrNull<Type> = Type | null;
type OneOrMany<Type> = Type | Type[];

// type OneOrManyOrNull<Type> = OneOrMany<Type> | null
type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;

// type OneOrManyOrNullStrings = OneOrMany<string> | null
type OneOrManyOrNullStrings = OneOrManyOrNull<string>;
来源:https://www.cnblogs.com/feixianxing/p/typescript-handbook-object-type-optional-readonly-index-signatures-extends-intersection-generic.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: [TS手册学习] 04_对象类型