TypeScript版本: 2.1.1
码
type A = { a: string; }
type B = { b: string; }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// use AorB.a
}
预期行为:
该代码编译没有错误。 即使a
在工会的所有组成部分上都不存在(必需),但存在于某些工会上的事实也应允许我检查.a
并使用(如果存在)。
实际行为:
Typescript抱怨:“属性a在AorB类型上不存在...属性a在类型B上不存在。”
医生说:
为了使相同的代码正常工作,我们需要使用类型断言:
let pet = getSmallPet();
if ((<Fish>pet).swim) {
(<Fish>pet).swim();
}
else {
(<Bird>pet).fly();
}
http://www.typescriptlang.org/docs/handbook/advanced-types.html
然后在您的示例中:
if ((<A>AorB).a) {
// use AorB.a
}
这里的问题是,因为B
没有声明a
属性,所以它在运行时可能具有任何可能类型的a
属性(因为您可以分配一个对象,只要它具有字符串类型的b
属性,就可以将具有任何属性集的对象分配给B
)。 您可以使其在B
明确声明a: undefined
属性(从而确保B
不会具有某些随机的a
属性)使其工作:
type A = { a: string; }
type B = { b: string; a: undefined }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// Ok
}
很有道理。 脑放屁。
如果在类型B上定义a: undefined
,则在创建/传递变量时必须将其设置为undefined
。
为了解决这个问题,您可以将a
为a?: undefined
,如果忽略它,打字稿将很高兴。
如果我正确理解注释,则应该可以(但会抛出;在操场上经过测试):这是否是错误? 🤔
type LinkProps = {
to: string;
onClick?: undefined;
// Link specific props:
target: string;
}
type ButtonProps = {
to?: undefined;
onClick: Function;
// Button specific props:
disabled: boolean;
}
type ActionProps = LinkProps | ButtonProps;
const Action = (props: ActionProps) =>
props.to ?
'Link with target: ' + props.target // Error not on ButtonProps
:
'Button with disabled: ' + props.disabled; // Error: not on LinkProps
Action({
to: 'dssd',
target: '_blank'
});
我一点都不明白。 if ((<A>AorB).a)
与if (A.a)
吗,因为您要强制其返回A
?
如果在类型B上定义
a: undefined
,则在创建/传递变量时必须将其设置为undefined
。
为了解决这个问题,您可以将a
为a?: undefined
,如果忽略它,打字稿将很高兴。
可能会更好a?: never
,现在您不能错误地分配undefined
如果您不给每个工会会员取名怎么办? (不能在没有断言类型名称的情况下进行上述类型断言,可以吗?)
type u = "str" | {prop:"val"};
function f(arg:u){return arg.prop} // TypeScript: Property 'prop' does not exist on type 'u'
有什么办法吗?
我在书上找到了解决方案:
interface A { x: number;}
interface B { y: string;}
function doStuff ( q: A | B ) {
if ( 'x' in q) {
// if type A...
}
else {
// if type B...
}
}
摘录自:Basarat Ali Syed。 “ TypeScript深入研究”。 苹果书。
一个对象上的属性,可以用作类型保护,并且TypeScript可以知道您使用了哪种类型。
type ColorItemType = {
colorId: number,
colorName: string,
}
type NumItemType = {
numId: number,
numName: string
}
type ResType = {
itemId: number,
// 0 color 1 num
type: number,
itemInfo: {
colorList: Array<ColorItemType>
numList: Array<NumItemType>
}
}
const request = () => {
return [{
itemId: 1,
type: 0,
itemInfo: {
colorList: [{
colorId: 1,
colorName: 'blue'
}],
numList: []
}
}];
};
const dataSource: Array<ResType> = request();
const formatData = dataSource.map(dataItem => {
const list: Array<ColorItemType | NumItemType> = dataItem.type === 1 ? dataItem.itemInfo.numList : dataItem.itemInfo.colorList;
return list.map(listItem => {
return {
// An error will be reported here
value: listItem.numId || listItem.colorId,
label: listItem.numName || listItem.colorName
};
});
});
这里的问题是,因为
B
没有声明a
属性,所以它在运行时可能具有任何可能类型的a
属性(因为您可以分配一个对象,只要它具有字符串类型的b
属性,就可以将具有任何属性集的对象分配给B
)。 您可以使其在B
明确声明a: undefined
属性(从而确保B
不会具有某些随机的a
属性)使其工作:type A = { a: string; } type B = { b: string; a: undefined } type AorB = A | B; declare const AorB: AorB; if (AorB.a) { // Ok }
对我不起作用07.10.2020
而且我认为TS的这种行为不好,因为它对开发人员的帮助不大。
最有用的评论
我在书上找到了解决方案:
摘录自:Basarat Ali Syed。 “ TypeScript深入研究”。 苹果书。
一个对象上的属性,可以用作类型保护,并且TypeScript可以知道您使用了哪种类型。