Skip to content

Commit 1eb6e0c

Browse files
committed
add test for schema methods typing scenario
1 parent d7a7e85 commit 1eb6e0c

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

test/types/schema.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,3 +1230,88 @@ async function gh13797() {
12301230
expectType<IUser>(this); return '';
12311231
} } });
12321232
}
1233+
1234+
async function gh14028() {
1235+
// Methods that have access to `this` should have access to typing of other methods on the schema
1236+
interface IUser {
1237+
firstName: string;
1238+
lastName: string;
1239+
age: number;
1240+
}
1241+
interface IUserMethods {
1242+
fullName(): string;
1243+
isAdult(): boolean;
1244+
}
1245+
type UserModel = Model<IUser, {}, IUserMethods>;
1246+
1247+
// Define methods on schema
1248+
const schema = new Schema<IUser, UserModel, IUserMethods>({
1249+
firstName: { type: String, required: true },
1250+
lastName: { type: String, required: true },
1251+
age: { type: Number, required: true }
1252+
}, {
1253+
methods: {
1254+
fullName() {
1255+
// Expect type of `this` to have fullName method
1256+
expectType<IUserMethods['fullName']>(this.fullName);
1257+
return this.firstName + ' ' + this.lastName;
1258+
},
1259+
isAdult() {
1260+
// Expect type of `this` to have isAdult method
1261+
expectType<IUserMethods['isAdult']>(this.isAdult);
1262+
return this.age >= 18;
1263+
}
1264+
}
1265+
});
1266+
1267+
const User = model('User', schema);
1268+
const user = new User({ firstName: 'John', lastName: 'Doe', age: 20 });
1269+
// Trigger type assertions inside methods
1270+
user.fullName();
1271+
user.isAdult();
1272+
1273+
// Expect type of methods to be inferred if accessed directly
1274+
expectType<IUserMethods['fullName']>(schema.methods.fullName);
1275+
expectType<IUserMethods['isAdult']>(schema.methods.isAdult);
1276+
1277+
// Define methods outside of schema
1278+
const schema2 = new Schema<IUser, UserModel, IUserMethods>({
1279+
firstName: { type: String, required: true },
1280+
lastName: { type: String, required: true },
1281+
age: { type: Number, required: true }
1282+
});
1283+
1284+
schema2.methods.fullName = function fullName() {
1285+
expectType<IUserMethods['fullName']>(this.fullName);
1286+
return this.firstName + ' ' + this.lastName;
1287+
};
1288+
1289+
schema2.methods.isAdult = function isAdult() {
1290+
expectType<IUserMethods['isAdult']>(this.isAdult);
1291+
return true;
1292+
};
1293+
1294+
const User2 = model('User2', schema2);
1295+
const user2 = new User2({ firstName: 'John', lastName: 'Doe', age: 20 });
1296+
user2.fullName();
1297+
user2.isAdult();
1298+
1299+
// Skip InstanceMethods
1300+
const schema3 = new Schema<IUser, UserModel>({
1301+
firstName: { type: String, required: true },
1302+
lastName: { type: String, required: true },
1303+
age: { type: Number, required: true }
1304+
}, {
1305+
methods: {
1306+
fullName() {
1307+
// As InstanceMethods type is not specified, expect type of this.fullName to be undefined
1308+
expectError<IUserMethods['fullName']>(this.fullName);
1309+
return this.firstName + ' ' + this.lastName;
1310+
}
1311+
}
1312+
});
1313+
1314+
const User3 = model('User2', schema3);
1315+
const user3 = new User3({ firstName: 'John', lastName: 'Doe', age: 20 });
1316+
expectError<string>(user3.fullName());
1317+
}

0 commit comments

Comments
 (0)