props
各种类型
<script lang="ts" setup>
import { ref, PropType } from 'vue';
interface listType {
addres: string;
code: number;
}
interface ftObj {
obj1: string[];
obj2: {
[key: string]: any;
};
}
const props = defineProps({
name: {
type: String as PropType<string>,
default: '默认footer name',
},
link: String as PropType<string>,
list: {
type: Array as PropType<listType[]>,
default: () => {
return [];
},
},
obj: {
type: Object as PropType<ftObj>,
default: () => {
return null;
},
},
});
</script>
emit defineEmits
string number简单字符类型
<input type="text" v-model="value" style="width: 150px" />
------------------------
// 定义事件的类型
type Emits = {
(event: 'updateValue', value: string): void;
};
// 使用类型定义的 defineEmits
const emitList = defineEmits<Emits>();
watch(value, (nevVal, old) => {
console.log('nevVal', nevVal);
emitList('updateValue', nevVal);
});
类型别名和接口之间的差异
类型别名和接口非常相似,在许多情况下,您可以在它们之间自由选择。 几乎所有的特性都可以在 中使用,关键的区别在于,一个类型不能被重新打开来添加新的属性,而一个接口总是可扩展的。interfacetype
–> 在 TypeScript 4.2 版之前,类型别名可能会出现在错误消息中,有时代替等效的匿名类型(这可能是可取的,也可能是不可取的)。接口将始终在错误消息中命名。
类型别名不能参与声明合并,但接口可以。
–> 接口只能用于声明对象的形状,而不能重命名基元。
–> 接口名称将始终以其原始形式出现在错误消息中,但仅当按名称使用时。
–> 在大多数情况下,您可以根据个人喜好进行选择,TypeScript 会告诉您是否需要其他声明。如果您想要启发式方法,请使用 直到您需要使用 中的特征。interfacetype
类型断言
有时,您将获得有关 TypeScript 无法知道的值类型的信息。
例如,如果你使用 ,TypeScript 只知道这将返回某种 ,但你可能知道你的页面将始终有一个给定的 ID。document.getElementByIdHTMLElementHTMLCanvasElement
在这种情况下,可以使用类型断言来指定更具体的类型:
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
== > 与类型注释一样,类型断言由编译器删除,不会影响代码的运行时行为。
您还可以使用尖括号语法(除非代码在文件中),这是等效的:.tsx
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
提醒:由于类型断言是在编译时删除的,因此没有与类型断言关联的运行时检查。 如果类型断言错误,则不会出现异常或生成异常。null
TypeScript 只允许转换为更具体或更不具体的类型版本的类型断言。 此规则可防止“不可能”的胁迫,例如:
const x = "hello" as number;
Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
有时,此规则可能过于保守,并且不允许可能有效的更复杂的胁迫。 如果发生这种情况,可以使用两个断言,首先是 to(或 ,我们将在后面介绍),然后是所需的类型:any unknown
const a = expr as any as T;
readonly
属性也可以标记为 TypeScript。 虽然它不会在运行时更改任何行为,但在类型检查期间无法写入标记为的属性。readonlyreadonly
interface SomeType {
readonly prop: string;
}
使用修饰符并不一定意味着一个值是完全不可变的,或者换句话说,它的内部内容不能改变。 它只是意味着属性本身不能被重写。readonly
interface Home {
readonly resident: { name: string; age: number };
}
function visitForBirthday(home: Home) {
// We can read and update properties from 'home.resident'.
console.log(`Happy birthday ${home.resident.name}!`);
home.resident.age++;
}
function evict(home: Home) {
// But we can't write to the 'resident' property itself on a 'Home'.
home.resident = {
Cannot assign to 'resident' because it is a read-only property.
name: "Victor the Evictor",
age: 42,
};
}
超额财产检查
请记住,对于像上面这样的简单代码,您可能不应该尝试“绕过”这些检查。 对于具有方法和保持状态的更复杂的对象文本,可能需要牢记这些技术,但大多数多余的属性错误实际上是 bug。
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any; //若获取的对象中 有超额的属性 则这样做
}
var s: SquareConfig = {
color: '121',
width: 123,
};
s.abc; //[propName: string]: any; 若没有这一段 将会报错
扩展类型
类型可能是其他类型的更具体版本是很常见的。
//例如,我们可能有一个类型来描述在美国发送信件和包裹所需的字段。BasicAddress
interface BasicAddress {
name?: string;
street: string;
city: string;
country: string;
postalCode: string;
}
//在某些情况下,这就足够了,但如果地址的建筑物有多个单元,则地址通常具有与之关联的单元号。 然后,我们可以描述一个 .AddressWithUnit
interface AddressWithUnit {
name?: string;
unit: string;
street: string;
city: string;
country: string;
postalCode: string;
}
//这可以完成工作,但缺点是,当我们的更改纯粹是累加时,我们不得不重复所有其他字段。 相反,我们可以扩展原始类型,只需添加 唯一的新字段。
我们可以这样做 ^^^
interface BasicAddress {
name?: string;
street: string;
city: string;
country: string;
postalCode: string;
}
interface AddressWithUnit extends BasicAddress {
unit: string;
}
interface 也可以从多种类型扩展>>>>>
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
interface ColorfulCircle extends Colorful, Circle {}
const cc: ColorfulCircle = {
color: "red",
radius: 42,
};
interface 也可以交叉类型>>>
使用运算符定义交集类型 &
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
function draw(circle: Colorful & Circle) {
console.log(`Color was ${circle.color}`);
console.log(`Radius was ${circle.radius}`);
}
// okay
draw({ color: 'blue', radius: 42 });
draw({ color: 'blue', radius234: 42 }); //这里会报错 因为没有 radius234 这个属性