我正在尝试创建一个 namespace /类/接口(interface)/类型(无论我需要什么,我都研究过它们,但似乎没有一个能够满足我的需要),它具有一些属性声明的strong>和方法类型。但其中也有子类型,如 Character.Stats
或Character.Currency
。 虽然仍然有只是 Character
作为有效类型
我需要如何格式化/布局我的打字文件才能允许此 classes.ts
文件是有效的 typescript 吗?
// statement to import Character type
class Player implements Character {
constructor (
public name: string, // a property
public stats: Character.Stats, // a property with a subtype typing
public currency: Character.Currency
) {
this.name = name
this.stats = stats
this.currency = currency
}
attack(target: Player) { // parameter is typing of its own class
console.log(`Attacked ${Character.name}`)
}
}
目前使用 typescript 可以实现这一点吗?
下面是我当前的测试代码库:
types/items.ts
export interface Type {
name: string,
sprite: string,
}
types/characters.ts
import * as Classes from "../classes";
export interface Stats {
health: number,
attack: number,
defence: number,
}
export interface Currency {
gold: number,
ridium: number
}
export interface Type {
name: string,
stats: Stats
currency: Currency
announce(sentence: string): void,
attack(target: Type): void,
heal(item: Classes.HealingItem): void
}
classes.ts
import * as Characters from "./types/characters";
import * as Items from "./types/items"
export class Character implements Characters.Type {
constructor(
public name: string,
public stats: Characters.Stats,
public currency: Characters.Currency
) {
this.name = name;
this.stats = stats
this.currency = currency
}
announce(sentence: string) {
console.log(`I, ${this.name}, ${sentence}`)
}
attack(target: Character): void {
this.announce(`am going to attack ${target.name}`)
}
heal(item: HealingItem) {
this.stats.health += item.healthPoints;
this.announce(`used ${item.name} to heal my hp from ${this.stats.health - item.healthPoints} to ${this.stats.health}`)
}
}
export class HealingItem implements Items.Type {
constructor(
public name: string,
public sprite: string,
public healthPoints: number
) {
this.name = name
this.sprite = sprite
this.healthPoints = healthPoints
}
}
index.ts
import * as Classes from "./classes";
const hero = new Classes.Character("Bob", // name
{ // stats
health: 100,
attack: 10,
defence: 25
},
{ // currency
gold: 50,
ridium: 0
}
)
const apple = new Classes.HealingItem("Apple", "./sprites/apple.sprite", 25);
hero.heal(apple);
hero.attack(hero);
当前的代码一切正常,但似乎当前的布局将来会引起问题。由于Items.Type
/Characters.Type
如果这是我能得到的最接近我想要的结果,那么......
简而言之...
我想要这样的东西
interface B {
x: string
}
namespace A {
export type v1 = number
export type v2 = boolean
export type v3 = B
}
let p: A = {
v1: 9,
v2: true,
v3: { x: "some string" }
};
let q: A.v1 = 2;
let r: A.v2 = false;
let s: A.v3 = { x: "strung" };
这不是有效的代码 let p: A
不允许将命名空间作为类型,但希望这能够描述我想要实现的目标。
最佳答案
如果我理解正确的话,你希望能够去掉.Type
后缀,这样你就可以直接写:
class Character implements Characters {
constructor(
public name: string,
public stats: Characters.Stats, // Type as a "member" of Characters
public currency: Characters.Currency
) {}
// Etc.
}
您感到困惑,因为您没有看到如何将 Stats
和 Currency
类型“嵌入”为 Characters
的“成员”。
一方面,如果它是一个接口(interface)
,任何“嵌入”类型也将被视为该接口(interface)的成员。
另一方面,如果它是一个命名空间
,它就不能直接用作类型本身。
您实际上可以同时实现这两个目标,因为命名空间
启用 merging转换为其他类型。
这样,我们就声明了接口(interface)
,并将其与命名空间
合并,使用相同的名称 .
export interface Characters {
name: string
stats: Characters.Stats
currency: Characters.Currency
announce(sentence: string): void
attack(target: Characters): void
heal(item: HealingItem): void
}
// Merge the namespace with the type of the same name
namespace Characters {
// Make sure the "embedded" types are explicitly exported
export interface Stats {
health: number
attack: number
defence: number
}
export interface Currency {
gold: number
ridium: number
}
}
顺便说一句,在构造函数中,如果类成员已用作具有相同名称和可见性修饰符的构造函数参数,则无需显式分配它们,请参阅 Class Parameter Properties :
TypeScript offers special syntax for turning a constructor parameter into a class property with the same name and value. These are called parameter properties and are created by prefixing a constructor argument with one of the visibility modifiers
public
,private
,protected
, orreadonly
.
关于typescript - 如何让接口(interface)包含子类型,同时本身也是有效类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74104654/